preg_match_all не работает на всех версиях php 7 - PullRequest
0 голосов
/ 24 сентября 2018

Моя среда разработки и производственная среда не имеют одинаковой точной версии

Моя среда разработки: PHP 7.0.31-1 + ubuntu14.04.1 + deb.sury.org + 1 (cli)

Моя рабочая среда: PHP 7.0.30 (cli)

Для того же текста это регулярное выражение

preg_match_all('/%occupancies%((?!%endoccupancies%).|\n)*%endoccupancies%/', $text, $matches);

найти совпадения в моей рабочей среде, но не в prod

Код простой:

http://sandbox.onlinephpfunctions.com/code/b4541decc65089269f6aae0e4392dc9081c14615

Есть ли способ исправить это, не обновляя мою версию php?

1 Ответ

0 голосов
/ 24 сентября 2018

Ваш шаблон содержит ((?!%endoccupancies%).|\n)* группу чередования, которая соответствует либо символу, отличному от символа разрыва строки, который не запускает подстроку %endoccupancies%, ни символу новой строки (так, например, он не совпадает с окончаниями CRLF).Эта группа количественно определяется с помощью *, и это означает, что каждый символ, соответствующий этой группе, сохраняется в слоте памяти группы 1 и перезаписывается при каждом захвате символа.Это создает огромные накладные расходы для механизма PCRE.

Переписать эту часть с шаблоном [^%]*(?:%(?!endoccupancies%)[^%]*)*.Он соответствует:

  • [^%]* - 0+ символов, отличных от %
  • (?:%(?!endoccupancies%)[^%]*)* - 0 или более вхождений
    • %(?!endoccupancies%) - a% сразу не сопровождается endoccupancies%
    • [^%]* - 0+ символов, отличных от %
...