Включение новых строк в функцию 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, когда они сами по себе, но не вместе!

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

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

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

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

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

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

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

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

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

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

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

С http://www.regular-expressions.info/dot.html :

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

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