Я пытаюсь сопоставить строку, которая может отображаться в нескольких строках. Он начинается и заканчивается определенной строкой:
{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 в ваше выражение.