web-dev-qa-db-ja.com

正規表現-一致したパターンを除外

除外するパターンは次のとおりです。

make it cheaper
make it cheapere
makeitcheaper.com.au
makeitcheaper
making it cheaper
www.make it cheaper
ww.make it cheaper.com

これらのいずれかに一致する正規表現を作成しました。しかし、私はこれら以外のすべてを手に入れたいです。私が作成したこの正規表現を逆にする方法がわかりません。

mak(e|ing) ?it ?cheaper

上記のパターンは、リストされているすべての文字列に一致します。今、私はそれが他のすべてと一致するようにしたい。どうすればいいのですか?

検索から、ネガティブな先読み/振り返りのようなものが必要なようです。しかし、私は本当にそれを理解していません。誰かが私を正しい方向に向けることができますか?

15
San

次のようにネガティブな先読みでそれを置くことができます:

_(?!mak(e|ing) ?it ?cheaper)
_

ただし、matchesを実行すると、それは機能しません。1、先を見ているだけなので一致しません。実際には何も一致していません。また、find1、次の文字が上記と一致しない文字列の多くの場所から開始できるため、何度も一致します。

これを修正するには、何をしたいかに応じて、2つの選択肢があります。

  1. exactlyのいずれかであるすべての文字列を除外する場合(「make it cheaperblahblah」は除外されません)、開始(_^_)および終了(_$_を確認します)の文字列:

    _^(?!mak(e|ing) ?it ?cheaper$).*
    _

    _.*_(ゼロ個以上のワイルドカード)は、実際に行われている一致です。負の先読みは、最初の文字からチェックします。

  2. すべての文字列含むのいずれかを除外する場合、一致するすべての文字の前に先読みが一致しないことを確認できます。

    _^((?!mak(e|ing) ?it ?cheaper).)*$
    _

    別の方法は、先読みの先頭にワイルドカードを追加することです(つまり、文字列の先頭から何かを含むすべての文字列を除外し、次にパターンを除外します)が、現時点ではこの利点はありません(任意の長さの先読みも、特定のツールでサポートされる可能性は低くなります)。

    _^(?!.*mak(e|ing) ?it ?cheaper).*
    _

_^_および_$_のため、findまたはmatchesを実行すると、上記のいずれかで機能します(ただし、matches、_^_はオプションであり、findの場合、先読みの外側の_.*_はオプションです。


1:呼ばれないかもしれませんが、多くの言語には、正規表現でmatchesおよびfindと同等の機能があります。


上記は、この質問に対する厳密な正規表現の回答です。

より良いアプローチは、元の正規表現(mak(e|ing) ?it ?cheaper)に固執し、使用しているツールまたは言語で直接一致を否定できるかどうかを確認することです。

たとえば、Javaでは、if (!string.matches(originalRegex))の代わりにif (string.matches(negLookRegex))(返されたブール値を否定する_!_に注意)を実行する必要があります。

23
Dukeling

ネガティブな先読みは、あなたが探しているものだと思います。たぶん試してみてください:

(?!.*mak(e|ing) ?it ?cheaper)

そして多分もう少し柔軟:

(?!.*mak(e|ing) *it *cheaper)

念のため、複数のスペースがあります。

7
Jerry