回答:
これは、貪欲な量指定子と貪欲でない量指定子の違いです。
入力を考えます101000000000100
。
を使用すると1.*1
、*
貪欲です-最後まで一致し1
、一致するまでバックトラックし1010000000001
ます。
.*?
貪欲ではありません。*
は何にも一致しませんが、1
一致するまで余分な文字を一致させようとし、最終的には一致し101
ます。
:全ての数量は、非欲張りモードを持っている.*?
、.+?
、.{2,6}?
、とさえ.??
。
あなたの場合、類似したパターンは<([^>]*)>
-大なり記号以外に一致します(厳密に言えば、>
中間<
と以外の0個以上の文字に一致します>
)。
Quantifier Cheat Sheetを参照してください。
?
と非貪欲の違いの例を説明したり示したりできます??
か?
"abc"
、正規表現は、/\w\w?\w/
完全な文字列にマッチします"abc"
-ので、?
貪欲です。/\w\w??\w/
怠惰です-一致するだけ"ab"
です。"abc"
後で失敗した場合にのみ、バックトラックして一致します。
デフォルトでの正規表現での繰り返しは貪欲です:彼らはできるだけ多くの担当者と一致しようとし、これが機能せずバックトラックする必要がある場合、パターン全体の一致が一致するまで、一度に1つ少ない担当者と一致しようとします見つかりました。その結果、最終的に試合が行われると、貪欲な繰り返しが可能な限り多くの担当者と一致します。
?
この動作を変更する数量詞繰り返しとして非貪欲とも呼ばれ、消極的(例えばJavaで)(そして時には「怠け者」)。対照的に、この繰り返しでは、最初にできるだけ少ない担当者とのマッチングを試みます。これが機能せず、バックトラックしなければならない場合、もう一度1つの担当者とのマッチングを開始します。その結果、最終的に試合が行われると、しぶしぶ繰り返しはできるだけ少ない担当者と一致します。
これら2つのパターンを比較してみましょう:A.*Z
とA.*?Z
。
次の入力があるとします。
eeeAiiZuuuuAoooZeeee
パターンは次の一致をもたらします。
A.*Z
1つの一致が得られます:AiiZuuuuAoooZ
(rubular.comを参照)A.*?Z
2つの一致が生成されます:AiiZ
およびAoooZ
(rubular.comを参照)まずは何をするかに焦点を当てましょうA.*Z
。それは最初に一致した場合にはA
、.*
多くのとしてマッチする、貪欲され、最初の試行.
可能な限りを。
eeeAiiZuuuuAoooZeeee
\_______________/
A.* matched, Z can't match
Z
が一致しないため、エンジンは逆戻りし、.*
一致する数を1つ少なくする必要があります.
。
eeeAiiZuuuuAoooZeeee
\______________/
A.* matched, Z still can't match
これはさらに数回行われ、最終的には次のようになります。
eeeAiiZuuuuAoooZeeee
\__________/
A.* matched, Z can now match
これでZ
一致できるため、全体的なパターンが一致します。
eeeAiiZuuuuAoooZeeee
\___________/
A.*Z matched
対照的に、A.*?Z
最初の消極的な繰り返しは.
できるだけ少なく一致し、その後.
必要に応じてより多くを取ります。これが、入力で2つの一致を見つける理由を説明しています。
以下は、2つのパターンが一致したものを視覚的に表したものです。
eeeAiiZuuuuAoooZeeee
\__/r \___/r r = reluctant
\____g____/ g = greedy
多くのアプリケーションでは、上記の入力の2つの一致が望ましいため.*?
、貪欲な代わりに消極的な方法を使用.*
して、一致の超過を防ぎます。ただし、この特定のパターンについては、否定された文字クラスを使用するより良い代替手段があります。
このパターンは、上記の入力のパターンA[^Z]*Z
と同じ2つの一致も検出しA.*?Z
ます(ideone.comに表示されます)。[^Z]
呼ばれるものである否定文字クラス:それは何も一致しますがZ
。
2つのパターンの主な違いはパフォーマンスにあります。より厳密に言えば、否定された文字クラスは、特定の入力に対して一方向にしか一致できません。このパターンに貪欲または消極的な修飾子を使用するかどうかは関係ありません。実際、一部のフレーバーでは、より優れた処理を行って、いわゆる所有量指定子を使用できます。これは、まったくバックトラックしません。
この例は説明的なものである必要があります。同じ入力を与えられた場合、貪欲、消極的、および否定された文字クラスパターンがどのように異なって一致するかを示しています。
eeAiiZooAuuZZeeeZZfff
これらは、上記の入力に一致するものです。
A[^Z]*ZZ
1つの一致が得られます:AuuZZ
(ideone.comで見られるように)A.*?ZZ
1つの一致が得られます:AiiZooAuuZZ
(ideone.comで見られるように)A.*ZZ
1つの一致が得られます:AiiZooAuuZZeeeZZ
(ideone.comで見られるように)以下は、それらが一致したものを視覚的に表したものです。
___n
/ \ n = negated character class
eeAiiZooAuuZZeeeZZfff r = reluctant
\_________/r / g = greedy
\____________/g
これらは、関心のあるいくつかのトピックをカバーする、stackoverflowに関する質問と回答へのリンクです。