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

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

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

Могу ли я захватить все между {a} and и {/a} with a regex? It seems the . doesn't match new lines, but I've tried the following with no luck: с regex? Кажется, . не соответствует новым линиям, но я попытался следующее, не повезло:

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

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

Ответ на: "Включение новых линий в функцию PHP preg_replace"

Количество ответов:3

Используйте s modifier modifier: :

$template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/s', 'X', $template, -1, $count );
//                                                ^
echo $count;
символы." " -28-" Вам нужно будет добавить задний / s флаг к вашему выражению.

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

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

"Точка соответствует одному персонажу,

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

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

Теперь, причина того, что regex не работает, как вы намеревались, потому что точка теряет свое особое значение, когда он появляется внутри класса символов (квадратные скобки) - так [.\n] just matches a dot or a linefeed. What you were looking for was просто соответствует точка или linefeed. То, что вы искали было (?:.|\n), but I would have recommended matching the carriage-return as well as the linefeed: , но я бы рекомендовал соответствия перевозки-возвращения, а также linefeed:

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

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

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

Однако, есть еще одна проблема с оригинальным regex, который все еще присутствует в этом: + is greedy. That means, if there's more than one жадный. Это означает, что, если в тексте есть более чем одна последовательность {a}...{/a} sequence in the text, the first time your regex is applied it will match all of them, from the first , то при первом применении вашего regex он будет соответствовать всем из них, от первого {a} to the last до последнего {/a}. The simplest way to fix that is to make the . Самый простой способ исправить это, чтобы сделать + ungreedy (a.k.a, "lazy" or "reluctant") by appending a question mark: ungreedy (ака, "ленивый" или "неохотно"), прикрепя вопросительный знак:

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

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