PHP функция preg_match обрезает текст

verfaa

Профессор
Регистрация
29 Янв 2007
Сообщения
416
Реакции
49
Из формы приходит текст вида
[reply-to=16]
reply to comment
another text

Пытаюсь его обработать функцией PHP preg_match, но по непонятной для меня причине в карманы попадает лишь последняя строка текста. Т.е. код:

PHP:
    $text = <<<EOL
    [reply-to=16]
    reply to comment
    another text
    EOL;
    preg_match("#\s?(\[reply\-to=(\d+)\])?(.*)$#iu", $text, $poc);
    print_r($poc);

выдаёт:

Код:
    Array
    (
        [0] =>
    another text
        [1] =>
        [2] =>
        [3] => another text
    )

Хотя в $poc[0] я ожидаю увидеть весь текст, а в $poc[3] весь текст без [reply-to=16]

В чём ошибка и как её исправить?
 
Проблема в вашем регулярном выражении связана с охватом оператора .*, который пытается захватить как можно больше символов, включая [reply-to=16], и поэтому в результате получается только последняя строка текста.

Чтобы исправить это, вы можете использовать оператор .*?, который захватит как можно меньше символов, чтобы соответствовать вашему шаблону.


как-то так:
Код:
$text = <<<EOL
[reply-to=16]
reply to comment
another text
EOL;

preg_match("#\s?(\[reply\-to=(\d+)\])?(.*?)$#ius", $text, $poc);
print_r($poc);
 
Да, это типичная ошибка знакомства с regexp. Сам на нее попадался по началу.
Есть два варианта квантификаторов в регулярных выраениях greedy (жадные) и не жадные.
По умолчанию .* - жадный и везде его приводят в пример. Но при этом он может немного "странно" себя вести, если не понимать, как он работает.

Жадные квантификаторы пытаются захватить как можно больше символов, соответствующих шаблону.
Примеры для текста text = "ababab"
a.*b - в этом примере .* - жадный квантификатор, который пытается захватить как можно больше символов между "a" и "b". Он захватывает всю строку, включая все промежуточные "ab". Поэтому результатом будет "ababab".
Не жадные (Non-Greedy) квантификаторы захватывают минимальное количество символов, соответствующих шаблону.
a.*?b - в этом примере .*? - не жадный квантификатор, который захватывает минимальное количество символов между "a" и "b". Он захватывает только первую пару "ab". Поэтому результат будет "ab".

Еще с толку бывает сбивает, что обычно выражение работает до конца строки, а не до конца текста. Поэтому "не жадные" иногда "правильно" отрабатывают, а инога нет. Не всегда понять это можно с ходу
 
Назад
Сверху