[PHP5] Проблемы с регулярными выражениями

otets-mihail

Чуваки, а бывало ли у вас такое, что при переходе с php4 на php5 у вас переставали правильно работать функции с регулярными выражениями?
 
[forum ~]$ cat test.php
<?

d_dummy("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nd");
d_dummy("\n\n\n\n\n\n\n\n\n\n\n\n\nd");

function d_dummy($instr)
{
echo("Start: '$instr'\n");
$instr = preg_replace("/(\s|\n)*qd/s","bar", $instr);
echo("Finish: '$instr'\n");
}

?>
[forum ~]$ php4 test.php |wc && php5 test.php | wc
138 12 180
84 11 125
[forum ~]$


(Вставьте сюда ваш любимый поисковик) сразу же выдает ссылку на сей дивный баг http://bugs.php.net/bug.php?id=36983 , но решения проблемы я пока так и не смог найти.
Увеличение backtrack_limit приводит лишь к тому, что php5 зависает на длительное время:
 
[forum ~]$ php4 test.php |wc && php5 -d pcre.backtrack_limit=4294967295 test.php | wc
138 12 180
^C

Более того, как я понял, обе версии php используют одну и ту же библиотеку PCRE, что весьма странно.
 
[forum ~]$ ldd /usr/bin/php4 | grep pcre && ldd /usr/bin/php5 | grep pcre
libpcre.so.3 => /usr/lib/libpcre.so.3 (0x00007fb5fdcfb000)
libpcre.so.3 => /usr/lib/libpcre.so.3 (0x00007ffb43a61000)
[forum ~]$

Мб кто сталкивался с решением, более изящным чем делать popen("perl -e <regexp function>") вместо preg_replace? :)

Marusetta

ага, я неправ
а так бы и не знал
Сообщение удалил

uncle17

не надо

artimon

Не было, но баг странный, да.

artimon


One comment about 5.2.x and the pcre.backtrack_limit:
Note that this setting wasn't present under previous PHP releases and the behaviour (or limit) under those releases was, in practise, higher so all these PCRE functions were able to "capture" longer strings.
With the arrival of the setting, defaulting to 100000 (less than 100K you won't be able to match/capture strings over that size using, for example "ungreedy" modifiers.
So, in a lot of situations, you'll need to raise that (very small IMO) limit.
The worst part is that PHP simply won't match/capture those strings over pcre.backtrack_limit and will it be 100% silent about that (I think that throwing some NOTICE/WARNING if raised could help a lot to developers).
There is a lot of people suffering this changed behaviour from I've read on forums, bugs and so on).
Hope this note helps, ciao :-)
Похоже, что в PHP4 изначальный лимит просто больше.

artimon

Решение очевидно: переписать выражение так, что оно не бактрекилось миллионы раз

otets-mihail

Я же написал, что тут не в лимите дело, а в алгоритме. Пхп4 же работает как-то.

Увеличение backtrack_limit приводит лишь к тому, что php5 зависает на длительное время:



code:[forum ~]$ php4 test.php |wc && php5 -d pcre.backtrack_limit=4294967295 test.php | wc
138 12 180
^C

korsar0156

\n входит в множество \s (при включенном флаге /s так что зависаем мы на проверке всех вариантов представления
\n\n\n... (\n\n\n..., \s\n\n..., \n\s\n..., ...)
надо переписывать регексп
UPD: ну или игнорировать ошибки и вместо возвращенного NULL использовать исходное значение

rosali

замени (\s|\n) на ([\s\n])
home-setia:~$ php5 test.php | wc
138 12 180

slonishka

ШАМАН! : DD

artimon

В этом примере вообще можно (\s|\n) на \s заменить :)
Оставить комментарий
Имя или ник:
Комментарий: