7

これ:

preg_match('~foo(.*?)(bar)?~','foo bar',$m);

私にこれを与える:

Array
(
    [0] => foo
    [1] => 
)

私はこれについてちょっと混乱しています。遅延一致であるため、グループ 1 が空の文字列を提供していることがわかります。しかし、(bar)?欲張ってキャプチャ グループ 2 を与えてはいけませんか?

私が得るべきものは

Array
(
    [0] => foo
    [1] => 
    [2] => bar
)

[1]スペースはどこですか。それでも..これは起こっていません。なんで?

4

3 に答える 3

5

ここでの答えは驚くほど簡単です。最初のグループは (最初のパスで) 何にも一致せず、スペースにも一致しません。2 番目のグループは、スペースを「バー」と一致させようとしますが、もちろん失敗します。一致する HAS の背後に何かがある場合、エンジンはバックトラックし、スペースに一致する最初のキャプチャ グループを展開します。しかし、今のままでまったく問題ないので (2 番目のグループは実際には空になる可能性があります)、そのままです。

あなたが期待するものを生成するには、これを試してください:

preg_replace('~foo(.*?)(bar)?_~', 'foo bar_', $m);


編集で、別のキャプチャ グループを追加しました。(.*) は 2 になりました。ご想像のとおり、文字列の最後まで一致します。その通りです。例を変更しただけです ^^

于 2013-11-03T21:30:43.280 に答える
3

いいえ、この動作は正しいです。遅延マッチングに関するドキュメントから:

量指定子の後に疑問符が続く場合、それは怠惰になり、代わりに可能な最小回数に一致します

(bar)?はオプションであるため(.*?)、正規表現が成功するために何かに一致する必要はありません。foobarの間のスペースがキャプチャされていないため、式を続けてbarに一致させることはできません。

于 2013-11-03T21:30:56.657 に答える
2

エントリ '0' は常に完全に一致するパターンであり、この場合はfooです。ただし、最初に一致するグループは、* が使用されているため、何も一致しません。2 番目のグループはオプションです。

于 2013-11-03T21:31:50.990 に答える