正規表現全体を否定する方法は?


95

たとえば、正規表現があります(ma|(t){1})。一致mat、一致しませんbla

私はこのようにそれが一致している必要があり、正規表現を否定したくblaないmatこの正規表現に何かを追加することによって。私は書くことができることを知っていますがbla、実際の正規表現はより複雑です。


5
余談ですが、{1}完全に無用です。(あなたがそれがいくつかの価値を提供すると思うなら、あなたは書いてみません((m{1}a{1}){1}|(t){1}){1}か?)
tripleee '27 / 06/27

回答:


100

負のルックアラウンドを使用します。 (?!pattern)

ポジティブルックアラウンドを使用して、パターンが一致することを表明できます。負のルックアラウンドは逆です。パターンが一致しないことを表明するために使用されます。一部のフレーバーはアサーションをサポートしています。一部は、後読みなどに制限を設けています。

regular-expressions.infoへのリンク

こちらもご覧ください

その他の例

これらは、おもちゃの問題の正規表現による解決策を演習として考案する試みです。ルックアラウンドを使用できるさまざまな方法(ネスト、ネストしてキャプチャするなど)を学ぼうとするなら、それらは教育的である必要があります。


2
regular-expressions.infoは、すべての正規表現にとって非常に優れたリソースです。
フライハイト2010

ルックアラウンドサポートはすべてありますか?では動作しませんgrep
Lazer、

Pattern.compile("(?!(a.*b))").matcher("xab").matches()である必要がtrueありますか?
Karl Richter

4
これは正しくないと思われます。正しい代替案については、stackoverflow.com / questions / 8610743 / …を参照してください。
Karl Richter、2015年

56

正規表現に完全に一致する文字列(つまり、mmbla大丈夫ですが、そうでmmはない)のみを許可したくない場合は、次のようにします。

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$)負の先読みです; 「現在の位置から開始して、次の数文字はor ではなく 、その後に文字列の終わりが続きます」と書かれています。先頭の開始アンカー()により、文字列の先頭に先読みが適用されます。それが成功した場合、mmt^.*は先進み、文字列を消費します。

参考までに、Javaのmatches()メソッドを使用している場合は、the ^とfinal は実際には必要あり$ませんが、害はありません。$先読み内部はかかわらず、必要とされます。


2
この回答の最も役立つ部分は.*、正規表現の末尾に追加する必要があることです。そうしないと、すべての文字列が拒否されます。
Rav

2
ネガティブルックアヘッドの$ 内側と.*最後のはどちらも重要なビットです。REと同様に、強力な単体テストのセットは、それを正しく行うために絶対に不可欠です。この答えは100%正解です。
トムディブル2018

1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

これは、指定された正規表現用です。
\ bは単語の境界を見つけるためのものです。
先読み(?= \ w)は、スペースを避けるためにここにあります。
元の正規表現に対する否定的な見方は、一致しないようにすることです。
最後に(\ w *)は、残っているすべての単語をキャッチします。
単語を保持するグループはグループ3
です。部分文字列は
単純な^(?!(?: m {2} | t)$)に一致するため、単純な(?!pattern)は機能しません細かさはフルラインなので機能しない

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.