Многострочное регулярное выражение не улавливает правильную маску

#regex #parsing

#регулярное выражение #синтаксический анализ

Вопрос:

Я пытаюсь поймать тег со специальным синтаксисом в файле с этим регулярным выражением :

 ([a-z0-9 >}/])({(var):([a-z0-9_/-.] )([?0-9] )*})([a-z0-9 {</])
 

Тег выглядит так :

  {var:contactText}
 

Но, как вы можете видеть в моем регулярном выражении, я хочу уловить, что находится до и после {var:something} . Мое выражение работает нормально, за исключением случаев, когда выражение является единственным в строке.
У меня был m флаг, чтобы предотвратить проблему, но это все еще не работает.

Живой пример: https://regex101.com/r/6T6OJm/1 /

Я что-то упускаю из виду? Кажется, это последняя часть, ([a-z0-9 {</]) которая не принимает разрыв строки, так каково же решение?

Ответ №1:

Как и cat, модификатор «многострочный» является ложным другом. Модификатор m не означает, что шаблон будет волшебным образом выполняться на нескольких строках, он только изменяет значение ^ $ привязок and (от начала / конца строки до начала / конца строки).

Все, что вам нужно, это определить потенциальные белые символы, используя s класс (который также включает в себя возврат каретки r и n символы новой строки).

 ~
    ([a-z0-9 >}/])
    s* ( { (var) : ([a-z0-9_/.-] ) ([?0-9] )? } ) s*
    ([a-z0-9 {</])
~xi
 

ДЕМОНСТРАЦИЯ

Обратите внимание, что многие символы в шаблоне не нужно экранировать. Поскольку шаблон немного длинный, я использовал модификатор x, чтобы не учитывать пробелы в шаблоне: он более удобочитаем.

Не уверен, что все группы захвата полезны.

Комментарии:

1. Спасибо за объяснение о «флаге m», я бы никогда не нашел!

2. @Camille: различные модификаторы описаны в руководстве по PHP , но некоторые из них отсутствуют и могут быть найдены в документации PCRE: pcre.org/pcre2.txt