二重引用符で囲まれたすべての文字列を一致させたいテキストがあるとします。ただし、これらの二重引用符内に二重引用符を含めることができます。例:
"He said \"Hello\" to me for the first time"
正規表現を使用して、これを効率的に一致させるにはどうすればよいですか?
二重引用符で囲まれたすべての文字列を一致させたいテキストがあるとします。ただし、これらの二重引用符内に二重引用符を含めることができます。例:
"He said \"Hello\" to me for the first time"
正規表現を使用して、これを効率的に一致させるにはどうすればよいですか?
このような入力を一致させるための非常に効率的なソリューションは、normal* (special normal*)*
パターンを使用することです。この名前は、Jeffrey Friedl の優れた書籍Mastering Regular Expressionsから引用されています。
これは、通常のエントリ (通常の部分) とその間の区切り文字 (特別な部分) で構成される入力を一致させるのに一般的に役立つパターンです。
すべての正規表現と同様に、より良い選択肢がない場合に使用する必要があることに注意してください。このパターンを使用して CSV データを解析することもできますが、たとえば Java を使用している場合は、代わりに OpenCSV を使用することをお勧めします。
また、パターン名の量指定子は星 (つまり、0 個以上) ですが、必要に応じて変更できることにも注意してください。
上記の例をもう一度見てみましょう。このテキスト サンプルは、入力のどこにでもある可能性があることを考慮してください。
"He said \"Hello\" to me for the first time"
どんなに頑張っても、「ドットと貪欲/怠惰な量指定子」の魔法をいくら使っても、問題を解決することはできません。代わりに、引用符の間の入力を通常と特別に分類します。
[^\\"]
。\\"
.これをパターンに代入するとnormal* (special normal*)*
、次の正規表現が得られます。
[^\\"]*(\\"[^\\"]*)*
全文を一致させるために二重引用符を追加すると、最終的な正規表現が得られます。
"[^\\"]*(\\"[^\\"]*)*"
これは空の引用符付き文字列にも一致することに注意してください。
ここでは、次の理由から、量指定子にバリアントを使用する必要があります。
簡単にするために、小文字の ASCII 文字のみが許可されていると仮定します。
サンプル入力:
the-word-to-match
再びノーマルとスペシャルに分解してみましょう。
[a-z]
;-
パターンの正規形は次のようになります。
[a-z]*(-[a-z]*)*
しかし、私たちが言ったように:
*
になる必要があります。+
*
は になり+
ます。最終的には次のようになります。
[a-z]+(-[a-z]+)*
その周りに単語アンカーを追加して、最終結果を取得します。
\b[a-z]+(-[a-z]+)*\b
上記の例は、 で置き換えることに限定されて*
い+
ますが、もちろん、必要な数のバリエーションを持つことができます。超古典的な例の 1 つは、IP アドレスです。
\d{1,3}
)、\.
),normal
回しか現れないため、量指定子はありません。normal
内側(special normal*)
も 1 回しか現れないため、量指定子はありません。(special normal*)
部分はちょうど 3 回表示されます{3}
。これにより、式が得られます(単語アンカーで装飾されています):
\b\d{1,3}(\.\d{1,3}){3}\b
このパターンの柔軟性により、正規表現ツールボックスの中で最も便利なツールの 1 つになります。ライブラリが存在する場合に正規表現を使用してはならない多くの問題が存在しますが、場合によっては正規表現を使用する必要があります。少し練習すれば、これはあなたの親友の 1 つになるでしょう。
(special normal*)
。したがって、非キャプチャ グループを使用することをお勧めします。たとえば、"[^\\"]*(?:\\"[^\\"]*)*"
引用符で囲まれた文字列に使用します。実際、あなたがそれを望んでいたとしても、この場合、キャプチャーが望ましい結果につながることはほとんどありません。なぜなら、このパターンを。ネット。(@ohaal に感謝)