регулярное выражение соответствует повторяющейся группе {0,2} или {0,4}, но {0,3} нет - PullRequest
4 голосов
/ 29 октября 2009

во-первых, это использует прег.

Строка, которую я пытаюсь найти:

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

Странно, если я удаляю одну букву "а", это работает. Также (\S*\s*){0,3}\Sp или (\S*\s){0,3}\S*p оба работают.

Может ли кто-нибудь объяснить, почему в третьем случае нет совпадений вместо "b c d xp"?

ТИА!

Ответы [ 2 ]

7 голосов
/ 29 октября 2009

Хороший вопрос.

Я попробовал другой язык с синтаксисом 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 просто не проверяет или имеет другое ограничение.
2 голосов
/ 29 октября 2009

preg_last_error() возвращает PREG_BACKTRACK_LIMIT_ERROR, поэтому увеличение лимита возврата должно, вероятно, решить проблему. Попробуйте

 ini_set('pcre.backtrack_limit', 500000);
...