正規表現で「逆一致」する方法は?


112

私はRegexBuddyを使用していますが、とにかくこのことに問題があります:\

ファイルを1行ずつ処理しています。思い通りのラインモデルを作りました。

次に、逆一致を実行したいと思います。つまり、6文字の文字列がある行を一致させたいのですが、これらの6文字がAndreaない 場合にのみ、どうすればよいですか。


編集:私はこの正規表現を使用するプログラムを作成しますが、PythonまたはPHPでは、いくつかの正規表現を学ぶために最初にこれを行っています:)さまざまな種類の行があり、正規表現を使用したかった興味のあるタイプを選択します。これらの行を取得したら、既知の値と一致しないように他のフィルターを適用する必要があります。それ以外のすべてのフィルターが必要です。(?!not-wanted)はかなりうまく機能しています。ありがとうございます。:-)

これが質問を明確にすることを願っています:)


実際、あなたがしていることについてもう少し情報を提供し、誰かが別の解決策を提供できるかどうかを確認した方がいいかもしれません。通常、各行に一致する正規表現を作成してファイル全体を解析しようとするのは、かなり複雑なルートです:)
Dan

回答:


70
(?!Andrea).{6}

正規表現エンジンが負の先読みをサポートすると仮定します。

編集:..または[A-Za-z]{6}、代わりに使用したい場合があります.{6}

編集(再度):先読みと後読みは、通常、正規表現の一致を「逆にする」正しい方法ではないことに注意してください。正規表現は、ネガティブマッチングを実行するために実際に設定されているわけではなく、それらを使用する言語に任せています。


@Vinko Vrsalovicが使用する^を追加して、 "ndrea \ n"に一致しないようにする必要があります
bdukes

2
。デフォルトでは\ nに一致しません(一部の言語(Perlなど)ではその動作をオンにすることができますが、デフォルトでは。はすべてに一致しますが\ n)。
ダン

1
(さらに、OPは文字列が行の先頭で発生する必要があるとは決して言及していませんでした)
Dan

1
OPとはどういう意味ですか?
Andrea Ambu

1
アンドレア:OPは「オリジナルのポスター」を意味するので、私はあなたに言及していました:)
Dan

47

Python / Javaの場合、

^(.(?!(some text)))*$

http://www.lisnichenko.com/articles/javapython-inverse-regex.html


4
これは機能しません。あなたはTempered Greedy Tokenのイディオムを考えています。しかし、ドットは前ではなく先読みのに行く必要があります。この質問を参照してください。しかし、そのアプローチはとにかくこのタスクにはやり過ぎです。
アランムーア

どの言語で書かれているかはわかりませんが、Sublimeテキストの魅力のように機能して、テストデータをクリーンアップしました。ありがとう!
Matthias dirickx

1
@AlanMoore実際には、この使用例ではほぼ問題なく動作します。ただし、some text行を開始すると、誤った結果が返されます。
Zenexer 2017

2
@ゼネクサー、それは私が言ったことです。ドットが先読みではなく先読みの後であれば、完全に機能します。
アランムーア

詳細はこちらのリンクをご覧ください。理由?!だけではなく、理由もわかりません!
Timo、

21

アラン・ムーアからのフィードバックで更新

PCREおよび類似のバリアントでは、値を含まないすべての行に一致する正規表現を実際に作成できます。

^(?:(?!Andrea).)*$

これは、調整済みの貪欲なトークンと呼ばれます。欠点は、パフォーマンスがよくないことです。


1
これは、長い形式の強化された貪欲トークンです。[\s\S]2番目の先読みの後にドット(またはJavaScriptでのみ有用)を置くだけで、最初のドットは不要になります^(?:(?!Andrea).)*$
Alan Moore

@AlanMooreいいね!そのように機能する確立されたパターンを見つけることができなかったので、自分のパターンを思いつきました。私があなたの答えをとるのではなく、あなたはそれをあなた自身のものとして提供するべきです。
Zenexer 2016

大丈夫です。すでに良い答えがたくさんあります。そして、あなたは自分でイディオムを発明したことに対する信用に値します。乾杯!
アランムーア

なぜあなたは使用を勧め[\S\s]ますか?OPは「Andrea」という単語を含まない、一致する行について話している。文字列全体にこの単語が含まれているかどうかをチェックすることではありません。何か不足していますか?
x-yuri 2017

@ x-yuri正しいと思います。私はおそらく、私が最初にこのページにアクセスしたという質問に答え、矛盾を無視しました。私の接続は今のところ答えを更新するには十分ではありません(<10 kbps)
Zenexer '29

11

どの言語を使用していますか?これには、正規表現実装の機能と構文が重要です。

先読みを使用できます。例としてpythonを使用する

import re

not_andrea = re.compile('(?!Andrea)\w{6}', re.IGNORECASE)

それを分解するには:

(?!Andrea)は、「次の6文字が「Andrea」でない場合に一致する」を意味します。もしそうなら

\ wは「単語文字」-英数字を意味します。これはクラス[a-zA-Z0-9_]と同等です

\ w {6}は、正確に6単語の文字を意味します。

re.IGNORECASEは、「Andrea」、「andrea」、「ANDREA」を除外することを意味します...

別の方法は、プログラムロジックを使用することです。Andreaに一致しないすべての行を使用し、それらを2番目の正規表現に通して6文字をチェックします。または、最初に6文字以上の文字を確認してから、それがAndreaと一致しないことを確認します。


7

否定先読みアサーション

(?!Andrea)

これは完全に逆の一致ではありませんが、正規表現を使用して直接実行できる最善の方法です。ただし、すべてのプラットフォームがそれらをサポートするわけではありません。


1
質問者が明確にするまで、試合は行頭から始めなければならないことはわかりません。では、なぜ^?
Hamish Downer

私は彼がラインの最初でチェックしたいと思っていたので、説明を付けて編集しました
Vinko Vrsalovic

5

RegexBuddyでこれを行う場合は、正規表現に一致しないすべての行のリストを取得する方法が2つあります。

テストパネルのツールバーで、テストスコープを「行ごと」に設定します。これを行うと、同じツールバーの「すべてをリスト」ボタンの下に、「一致しないすべての行をリスト」という項目が表示されます。([すべてリスト]ボタンが表示されない場合は、メインツールバーの[一致]ボタンをクリックしてください。)

GREPパネルで、「行ベース」および「結果を反転」チェックボックスをオンにして、grepするファイル内の一致しない行のリストを取得できます。


5

(?!実際に役立ちます。厳密に言えば、先読みは数学的に定義された正規表現ではありません。

逆正規表現は手動で作成できます。

これは自動的に結果を計算するプログラムです。その結果は機械で生成され、通常手書きのものよりもはるかに複雑です。しかし、結果は機能します。


1

私はこの方法を思いついただけで、ハードウェアに負荷がかかる可能性がありますが、機能しています。

正規表現に一致するすべての文字を空の文字列に置き換えることができます。

これはワンライナーです:

notMatched = re.sub(regex, "", string)

非常に複雑な正規表現を使用せざるを得ず、妥当な時間内にそのすべての部分を反転する方法を理解できなかったため、これを使用しました。

これは、一致オブジェクトではなく、文字列結果のみを返します!


-3

Perlでできること

process($ line)if($ line =〜!/ Andrea /);


4
その構文は間違っています。$行場合、私はあなたに平均プロセス($ライン)を考える〜/アンドレア/!
dland
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.