2017-02-17 3 views
1

私はパーサーを構築しています。さまざまな行からコメントを削除したいと思います。たとえば、regexを使用してコメントを削除する

variable = "some//thing" ////actual comment 

コメントマーカーは//です。この場合、variableには"some//thing"が含まれ、それ以外は無視されます。私は正規表現置換を使用してそれを行うことを計画しています。現在、私は(".*"|[ \t])*(\/\/.*)を正規表現として使用しています。ただし、それを置き換えると"some//thing" ////actual commentが完全に置き換えられます。

私は代わりに使うべき正規表現を見つけることができません。助けてくれてありがとう。

追加情報 - 私はnetcoreapp 1.1.0

編集してC#を使用しています - いくつかのケースは、ちょうど//line commentのようにコメントしてラインであるかもしれません。文字列にはエスケープされた引用符も含まれます。

+1

既存の言語を解析していますか、これはカスタム形式ですか? – Ryan

+0

カスタム言語です – Crimson7

+1

[このページはヘルプ](http://www.rexegg.com/regex-best-trick.html#notarzan)? [^ "] *" |(//.*) 'ですが、エスケープされた引用符は含まれません。例えば、\" // thing "'などです。 –

答えて

1

ここには醜い正規表現のパターンがあります。私はそれがうまくいくと信じています。私は構文エラーが含まれている行を含め、私が考えることができるすべての病理学的な例でそれを試しました。たとえば、引用符が多すぎるか、少なすぎる引用符付きの文字列、または二重引用符があります。したがって、ではなく、がエスケープされます。コメントに引用符で囲まれた文字列を使用しています。これは、私が選択肢を思い出させたいときにわかっています。

内に二重スラッシュがあり、一見して引用符付きの文字列であり、何らかの形でその文字列が不正であり、二重スラッシュが正しく引用された部分の外に合法的に終わる場合のみです。プログラマの意図ではなく、構文的に有効なコメントになります。だから、プログラマーの視点からは間違っていますが、ルールによって、それは本当にコメントです。意味は、パターンは上に上がるように見えます。

このパターンを使用すると、パターンはラインの非コメント部分を返します。パターンにはファイル全体に適用するための改行\nがあります。システムが改行を他の方法で解釈する場合は、たとえば\rまたは\r\nのように修正する必要があります。シングルラインモードで使用するには、選択した場合は削除できます。これは、1行の文字17と18にあり、複数行バージョンの5行目、6行目、7行目の印刷文字にあります。ただし、単一行モードの場合と同じようにそのまま置いておくことができます。また、複数行モードでは、空白のコード行、または最初の列からコメントが始まる行に改行を返します。その結果、新しいファイルに結果を書き込むと、行番号は元のバージョンと同じになります。比較を簡単にします。

ワンメジャーこのパターンの注意:正規表現エンジンではさまざまなレベルのサポートを持つグループ化構造を使用します。私は、これをYMMVで受け付けるのは.NETとPCREのエンジンだと思います。それは第三のタイプである:(?(_condition_)_then_|_else_)です。 _condition_パターンはゼロ幅アサーションとして扱われます。パターンが一致する場合、試行された一致で_then_パターンが使用されます。そうでない場合は_else_パターンが使用されます。その構造がなければ、パターンは珍しい長さに成長していて、私の病理検査の場合にはまだ失敗していました。

ここに示すパターンは、正規表現エンジンで見る必要があります。私はではない C#のプログラマーなので、引用符で囲まれた文字列をエスケープするというニュアンスはわかりません。すべてのバックスラッシュと引用符が正規表現エンジンによって正しく見られるように、このパターンをコードに取り入れることはあなた次第です。たぶんC#はPerlのheredoc構文に相当するかもしれません。

これは、使用するワンライナーのパターンです:

^((?:(?:(?:[^"'/\n]|/(?!/))*)(?("(?=(?:\\\\|\\"|[^"])*"))(?:"(?:\\\\|\\"|[^"])*")|(?('(?=(?:\\\\|\\'|[^'])*'))(?:'(?:\\\\|\\'|[^'])*')|(?(/)|.))))*) 

あなたは無視するパターンの空白オプションを使用する場合は、このバージョンを使用することができます

(?x) # Turn on the ignore white space option 
^(# Start the only capturing group 
    (?: # A non-capturing group to allow for repeating the logic 
     (?: # Capture either of the two options below 
      [^"'/\n] # Capture everything not a single quote, double quote, a slash, or a newline 
      | # OR 
      /(?!/) # Capture a slash not followed by a slash [slash an negative look-ahead slash] 
     )* # As many times as possible, even if none 
     (?(" # Start a conditional match for double-quoted strings 
       (?=(?:\\\\|\\"|[^"])*") # Followed by a properly closed double-quoted string 
      ) # Then 
      (?:"(?:\\\\|\\"|[^"])*") # Capture the whole double-quoted string 
      | # Otherwise 
      (?(' # Start a conditional match for single-quoted strings 
       (?=(?:\\\\|\\'|[^'])*') # Followed by a properly closed single-quoted string 
       ) # Then 
       (?:'(?:\\\\|\\'|[^'])*') # Capture the whole double-quoted string 
       | # Otherwise 
       (?([^/]) # If next character is not a slash 
       .) # Capture that character, it is either a single quote, or a double quote not part of a properly closed 
      ) # end the conditional match for single-quoted strings 
     ) # End the conditional match for double-quoted strings 
    )* # Close the repeating non-capturing group, capturing as many times as possible, even if none 
) # Close the only capturing group 

をこれはあなたのコードが可能になりますこの怪物を説明して、誰か他の人がそれを見るとき、または数ヶ月後に自分で作業しなければならないときには、WTFの瞬間はありません。私はコメントがそれをうまく説明していると思いますが、あなたが好きなように自由に変更することができます。

上記のように、条件付き一致のグループ分けは限られています。それが失敗する場所は、以前のコメントにリンクしたサイトにあります。 C#を使用しているので、私は.NET Regex Testerでテストを行うことにしました。これはこれらの構造を扱うことができます。それはいいリファレンスも含んでいます。側面が適切に選択されていれば、上記のいずれかのバージョンをテストして、それを試すこともできます。その複雑さを考慮すると、ファイルのデータや、夢見ることができるエッジケースや病理検査など、どこかでテストすることをお勧めします。

この小さなパターンを利用するには、電子メールアドレスをテストするパターンが78行×81行で、余分な数十の文字が必要です。 (私はは、電子メールアドレスをテストするために、または他の正規表現を使用しないことをお勧めします)。仕事に間違ったツール。)自分自身を怖がらせたい場合は、ex-parrotサイトでそれを覗いてみてください。私はそれとは何の関係もなかった!

+0

努力してくれてありがとうございますが、正規表現では、 "qwe" "qwe" \\ asd'のような引用符からコメントを分けることはありません。 \\。)* "|(\/\ /.*)'(https://regex101.com/r/GxcvJz/6)。私もリンクを見ました。その正規表現は怪物です。再び、努力のおかげで! – Crimson7

+0

私の間違い。私はフォワードスラッシュの代わりにバックスラッシュを使用しました。あなたのソリューションは完璧に動作します!加えて、文字列とコメントを手作業で分けることの頭痛を助長します。ありがとう、トン! – Crimson7

+0

動作しない場合がある場合は、コメントしてください。私はそれがすべての病理学的事件、たとえ文法的に無効な事件であっても、ペアのない見積もりを除いてトラップします。私は図書館に保管しておき、できるだけ良いものにしたいと思っています。 –

1

"[^"\\]*(?:\\[\W\w][^"\\]*)*"|(\/\/.*)

フラグ:グローバル

がいっぱい文字列やコメントを照合します。

グループ1:コメント。

コメントがない場合は、同じ一致するテキストに置き換えてください。それ以外の場合は、コメント自体にあなたのことをしてください。

+0

[link](https://regex101.com/r/Nkftcf/3)とどのように比較されますか?どちらが良いでしょうか? – Crimson7

関連する問題