含まれていないまでの正規表現


81

正規表現の場合、検索までの構文は何ですか?ちょっと好き:

Haystack:
The quick red fox jumped over the lazy brown dog

Expression:
.*?quick -> and then everything until it hits the letter "z" but do not include z

回答:


162

「検索するまで検索するXが、含まない」という明示的な言い方Xは次のとおりです。

(?:(?!X).)*

ここで、X任意の正規表現を使用できます。

しかし、あなたの場合、これはやり過ぎかもしれません-ここで最も簡単な方法は

[^z]*

これはを除くすべてに一致するzため、次のの直前で停止しzます。

だから.*?quick[^z]*一致しThe quick fox jumps over the laます。

ただし、注意すべき単純な文字が複数あるとすぐ(?:(?!X).)*に、たとえば

(?:(?!lazy).)*-単語の先頭まで何にでも一致しlazyます。

これは、先読みアサーション、より具体的には負の先読みを使用しています。

.*?quick(?:(?!lazy).)*一致しThe quick fox jumps over theます。

説明:

(?:        # Match the following but do not capture it:
 (?!lazy)  # (first assert that it's not possible to match "lazy" here
 .         # then match any character
)*         # end of group, zero or more repetitions.

さらに、キーワードを検索するときは、単語境界アンカーで囲むことをお勧めします。単語全体\bfox\bにのみ一致し、foxのキツネには一致しませんfoxy

注意

照合するテキストに改行も含めることができる場合は、正規表現エンジンの[すべてに一致するドット]オプションを設定する必要があります。通常、これ(?s)は正規表現の前に付けることで実現できますが、すべての正規表現エンジン(特にJavaScript)で機能するとは限りません。

代替ソリューション:

多くの場合、遅延数量詞を使用する、より単純で読みやすいソリューションを使用することもできます。数量詞に?を追加することにより*、現在の位置からできるだけ少ない文字に一致しようとします。

.*?(?=(?:X)|$)

任意の数の文字に一致し、直前X(任意の正規表現)または文字列の終わり(X一致しない場合)で停止します。これを機能させるには、「ドットがすべてに一致する」オプションを設定する必要がある場合もあります。(注:X交代から確実に分離するために、キャプチャしないグループを追加しました)


+1本当にいい答えです。残念ながら、では機能しませんgrepが、この答えは機能します。
アレクサンドルラヴォワ2013年

@AlexandreLavoie:興味深い。なぜもう一方が機能し、これが機能しないのですか?どちらも先読みアサーションを使用します。おそらくそれは、(?:...)捕獲していないグループのせいですか?それは動作し((?!X).)*ますか?
Tim Pietzcker 2013年

1
本当にわかりません。私は正規表現の専門家でもgrepでもありません。私はgrep、SQLのmysql bintransformetからの1つのデータベースのみに対する要求をフィルタリングするために使用していました。ここに獣があります:grep -Po "(?s)use database_to_keep(.*?)(?=^use)" mysql-bin.000045.sql > filtered.sql
アレクサンドルラヴォワ2013年

Upキーを押したとき、最後のコマンドは私が使用したコマンドではないため、bashの競合のように見えます:grep -Po "(?s)use database_to_keep(.*?)(?:(?!^use).)*" mysql-bin.000045.sql > filtered.sql
Alexandre Lavoie 2013年

1
グッド編集、@Tim、単に追加$の代替を:置き換える.*?(?=X).*?(?=X|$)
Wiktor第Stribiżew

15

先読み正規表現の構文は、あなたの目標を達成するためのお手伝いをすることができます。したがって、あなたの例の正規表現は

.*?quick.*?(?=z)

また.*?(?=z)先読みの前に遅延一致に注意することが重要です。式は、文字が最初に出現するまで部分文字列と一致しzます。

C#のコードサンプルは次のとおりです。

const string text = "The quick red fox jumped over the lazy brown dogz";

string lazy = new Regex(".*?quick.*?(?=z)").Match(text).Value;
Console.WriteLine(lazy); // The quick red fox jumped over the la

string greedy = new Regex(".*?quick.*(?=z)").Match(text).Value;
Console.WriteLine(greedy); // The quick red fox jumped over the lazy brown dog

0

これを試して

(.*?quick.*?)z

3
これには、試合の「z」が含まれます。これは、質問者が避けたいものです。おそらく、正規表現は「|」の用語であることが意図されています 代替、およびその代替正規表現は、複数の一致を実行するために使用されます。「z」が代替の別の用語と一致する文字列の先頭である場合、「z」は現在の一致によってすでに消費されているため、この一致は失われます。
SzczepanHołyszewski
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.