Подтвердить что ты не робот

Включение новых строк в функцию PHP preg_replace

Я пытаюсь сопоставить строку, которая может отображаться в нескольких строках. Он начинается и заканчивается определенной строкой:

{a}some string
can be multiple lines
{/a}

Могу ли я взять все между {a} и {/a} с помощью регулярного выражения? Кажется. не соответствует новым строкам, но я не пробовал следующее:

$template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/', 'X', $template, -1, $count );
echo $count; // prints 0

Он соответствует. или \n, когда они сами по себе, но не вместе!

4b9b3361

Ответ 1

Используйте s модификатор:

$template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/s', 'X', $template, -1, $count );
//                                                ^
echo $count;

Ответ 2

Я думаю, у вас больше проблем, чем просто точка, не соответствующая новой строке, но позвольте мне начать с рекомендации по форматированию. Вы можете использовать практически любой символ пунктуации как разделитель регулярных выражений, а не только косую черту ('/'). Если вы используете другого персонажа, вам не придется скрывать косые черты в регулярном выражении. Я понимаю, что "%" популярен среди PHPers; что сделало бы ваш шаблонный аргумент:

'%\{a\}([.\n]+)\{/a\}%'

Теперь причина, по которой регулярное выражение не работает так, как вы намеревались, состоит в том, что точка теряет свое особое значение, когда она появляется внутри класса символов (квадратные скобки) - поэтому [.\n] просто соответствует точке или строке. То, что вы искали, было (?:.|\n), но я бы рекомендовал сопоставить возврат каретки, а также строку перевода:

'%\{a\}((?:.|[\r\n])+)\{/a\}%'

Это потому, что слово "новая линия" может ссылаться на стиль "\n" в стиле Unix, стиль "\ r\n" в стиле Windows или более старый стиль "\ r". Любая данная веб-страница может содержать любую из них или смесь из двух или более стилей; сочетание "\n" и "\ r\n" очень распространено. Но с режимом /s (также называемым однострочным или DOTALL-режимом) вам не нужно беспокоиться об этом:

'%\{a\}(.+)\{/a\}%s'

Однако существует еще одна проблема с исходным регулярным выражением, которое все еще присутствует в этом: + является жадным. Это означает, что если в тексте присутствует более одной {a}...{/a} последовательности, при первом применении регулярного выражения он будет соответствовать всем им, начиная с первого {a} и до последнего {/a}. Самый простой способ исправить это, чтобы сделать + ungreedy (a.k.a, "ленивый" или "неохотный" ), добавив знак вопроса:

'%\{a\}(.+?)\{/a\}%s'

Наконец, я не знаю, что делать с '$' перед открывающей цитатой вашего аргумента шаблона. Я не делаю PHP, но это выглядит как синтаксическая ошибка для меня. Если бы кто-то мог воспитывать меня в этом вопросе, я был бы признателен.

Ответ 3

От http://www.regular-expressions.info/dot.html:

"Точка соответствует одному символу, не заботясь о том, что это за символ. Единственное исключение - новая строка символы".

вам нужно будет добавить к вашему выражению флаг trailing/s.