2013-05-19 22 views
6

私はWindows Powershellを使ってテストしている.net regexを持っています。次のように出力されます貪欲でない正規表現は、greedyの結果を与える

> [System.Text.RegularExpressions.Regex]::Match("aaa aaa bbb", "aaa.*?bbb") 


Groups : {aaa aaa bbb} 
Success : True 
Captures : {aaa aaa bbb} 
Index : 0 
Length : 11 
Value : aaa aaa bbb 

私の期待は年代の第二のグループは、式を満たすのに十分であるよう?数量詞を使用すると、試合はaaa bbbにさせるというものでした。非貪欲な量指定子の私の理解に欠陥があるのですか?または私は間違ってテストしていますか?

注:

regex: aaa.*?bbb 
result: aaa aaa bbb 

regex: aaa.*bbb 
result: aaa aaa bbb bbb 

正規表現エンジンがaaaの最初の発生を発見し、その後、すべての文字(.*?)をスキップ:Regular Expression nongreedy is greedy

答えて

5

これはよくある誤解です。遅れた数量詞は、可能な限り最短の一致を保証しません。現在の位置からの現在の量指定子が、全体的な一致に必要な文字より多くの文字と一致しないことを確認するだけです。

可能な限り最短の一致を確実にしたい場合は、それを明示する必要があります。この場合、.*?の代わりに、aaaでもbbbでもないものと一致するサブレジオが必要です。結果として得られる正規表現は、

aaa(?:(?!aaa|bbb).)*bbb 
+0

私は最初にやっていたはずのことをやって、フリードルの関連する章に相談しました。それは私に 'aaa((?!aaa)。* bbb'に導かれました。あなたの答えには、サブ式を非キャプチャとし、bbbを負の数でテストするという追加の詳細があることを除いて、先のことを考える。いい答え。 –

5

が文字列aaa aaa bbb bbbのための結果を比較として、これははっきりと同じ問題ではありませんに最初のの出現はbbbですが、欲張りのオペレーター(.*)の方がより大きな結果を見つけることができますので、に一致しますtの出現はbbbです。

+0

です。これは何が起きているのかを明確に説明しています。 +1 – duozmo

0

まあ、それは本当に簡単です、我々は、我々は、この正規表現aaa.*?bbbを持って見てみましょう

BBB以下の文字列

のAAA AAAを持っています。正規表現エンジンはaaa

AAAのAAA BBB

正規表現エンジンは今.*?bbb持って開始します。それはspace

AAA スペースのAAA BBB

を進めてまいりますが、我々はまだbbbまでいくつかの文字がありますか?だから、正規表現エンジンは、最後に正規表現エンジンがマッチします、それは方法です続けると

AAA AAAスペース BBB

の第2のセットを一致しますbbb

のaaa AAA bbb


我々は唯一の二aaaを一致させたいのであれば、我々は次の正規表現を使用することができ、見てみましょう:

(?<!^)aaa.*?bbb、これは文の先頭にないaaaと一致することを意味します。

また、aaa(?= bbb).*?bbbを使用することもあります。これは、aaaに続いてspace bbbと一致することを意味します。 2 -

は、それが1の作業を参照してください。

ちょうど私の感覚に来ましたが、なぜaaa bbbを直接使用しないのですか?

1

これは貪欲/怠惰な問題ではありません。問題は、文字列が左から右に分析されるという事実にあります。最初のaaaがマッチすると、正規表現エンジンは完全なパターンを持つように文字を1つずつ追加します。

例では、最初のaaaが一致し、正規表現エンジンがすべての最後の文字を取り、完全に一致するまで文字ごとにバックトラックするという同じ結果が得られることに注意してください。

関連する問題