Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

PCRE 8.10

Заодно, после перевода проекта на UTF-8, стали появляться первые проблемы с новой библиотекой PCRE. Как я писал, для того, чтобы в PCRE некоторые комбинации работали как положено, мне перешлось перейти на версию 8.10.

Для этого я собрал специальный модуль YGX, это тот же extension PCRE, только с новой версией библиотеки (кстати, модуля пришлось делать два — для PHP 5.2.xx и 5.3.xx отдельно).

Теперь, когда у меня в PHP два вида функций — preg_* (старая PCRE) и ygx_* (новая PCRE 8.10), можно сравнивать поведение обоих. Вот первый небольшой тест:

bolk-dev ~/wiki $ php -r 'var_dump(ygx_replace("/a?/u", "", "abc"));'
string(2) "bc"
bolk-dev ~/wiki $ php -r 'var_dump(preg_replace("/т?/u", "", "тест"));'
string(4) "ес"
bolk-dev ~/wiki $ php -r 'var_dump(ygx_replace("/т?/u", "", "тест"));'
NULL

Как видно, PCRE 8.10 в последнем случае выдаёт NULL. Такое поведение похоже на баг. Выражение, конечно, довольно бессмысленное, но на практике оно встретилось в составе более сложного.

Чтобы в этом случае не получался NULL (хотя правильного результата всё равно не будет), можно поставить «глагол» «(*FAIL)» (это специальное значение, который ни с чем не совпадает):

bolk-dev ~/wiki $ php -r 'var_dump(ygx_replace("/(*FAIL)т?/u", "", "тест"));'
string(8) "тест"

Стоит ввести в выражение хоть что-то, что не содержит квантификатора «ноль или…» и NULL исчезает.

Что делать в этом случае, кроме как переписать регулярное выражение полностью, я пока не придумал.