2017-06-20 25 views
0

ここで私はプログラマーがおそらく一日もしなければならなかった何かをしようとしています。Regexp puzzle:encapsulated structures

私は自分のコードにこれらのネストされたマクロをすべて持っています。コメントがまだない場合は#ifが終了する各#endifの隣にコメントします。正規表現は私のためにそれを行うことができますか?今まで*と+はNotepad ++であまりにも貪欲で、私が理論的に怠惰なバージョン*を使用したとしても? +?この

#if A 

Code 

#if B 

Code 

#if C 

Code 

#endif /* C */ 

Code 

#endif /* B */ 

Code 

#endif /* A */ 
+0

正規表現ではネストされた構造を処理できません。バックトラックの拡張機能を使用しても、それが可能であるかどうかはわかりません。 –

+0

これは[通常の言語](https://en.wikipedia.org/wiki/Regular_language)ではないため、一般的には不可能です。それを証明する1つの方法は、一般的なケースでは、有限数の状態で解析することができないということです。 –

+0

メモ帳++を使用している場合、なぜNotepad ++でタグ付けしませんでしたか? NPPの正規表現フレーバはBoostであり、再帰を処理できます。 –

答えて

1

の中へ...

例えば

この

#if A 

Code 

#if B 

Code 

#if C 

Code 

#endif 

Code 

#endif /* B */ 

Code 

#endif 

これは、単一の正規表現で行うことができますか?いいえ!

正規表現を使用してメモ帳++でこれを行うことはできますか? HELL YEAH !!!

  1. オフ. matches newlineをオフにします。
  2. \r\nをすべて\nに置き換えてください。これにより、Windowsでは正規表現がはるかに簡単になります。必要に応じて後で変更することができます。

  3. #endifに置き換えて、既存の#endifマーキングをすべてクリアします。

  4. 我々は唯一#if...#endifラインに焦点を当てる必要がありますので、我々は;$0^(?!#(if|endif)).*を交換することにより、他のすべてを無視します。だから;は私たちの '無視'マーカーです。

  5. 次に、間に無視される線しかない#if - #endifのペアを繰り返し変更します。
    したがって、「すべて置換」を繰り返して
    ^#if(.+)\n((;.*\n)*)#endif

    ;#if$1\n$2;#endif /* $1 */とします。

    これは、最小のネストレベルですべて#if - #endifsにコメントを適用し、;とマークするので、次に[すべて置換]をクリックすると無視されます。
  6. 完了したら、^;(.+?\n)$1に置き換えて無視マーカーを削除します。

VOILA!

+0

ああ! find/replaceを繰り返し使用することについて考えずに、途中でものを修正しました。この考え方は一般的に将来的には間違いありません。 – Charles