4

まず、これはpregを使用しています。

一致させようとしている文字列:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp

私の正規表現とその一致:

(\S*\s*){0,1}\S*p = "d xp"
(\S*\s*){0,2}\S*p = "c d xp"
(\S*\s*){0,3}\S*p = NO MATCH (expecting "b c d xp"
(\S*\s*){0,4}\S*p = entire string
(\S*\s*){0,5}\S*p = entire string

奇妙なことに、単一の「a」を削除すると機能します。また、(\S*\s*){0,3}\Spまたは(\S*\s){0,3}\S*p両方が機能します。

「bcd xp」ではなく、3 番目のケースで一致しない理由を誰か説明できますか?

ティア!

4

2 に答える 2

7

良い質問。

Perl RE 構文もある別の言語である Ruby を試してみたところ、期待どおりの文字列が返されました。

$ irb
>> s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp'
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp"
>> s[/(\S*\s*){0,3}\S*p/]
=> "b c d xp"

これは、インタプリタのバグを見つけたと思いました...

しかし、私たちは今それを知っています

  • あなたの RE は正しかったし、その結果に対する期待も正しかった
  • PHP にはバックトラックに制限があり、問題は式が制限に達したことでした。Rubyはチェックしないか、別の制限があります。
于 2009-10-29T02:21:11.203 に答える
2

preg_last_error()PREG_BACKTRACK_LIMIT_ERROR を返すため、バックトラック制限を増やすとおそらく問題が解決するはずです。試す

 ini_set('pcre.backtrack_limit', 500000);
于 2009-10-29T05:12:51.027 に答える