Вот строки, которые я хотел бы удалить из тегов {{if}}
и {{\if}}
, я имею в виду первый и последний (внутренние будут проверены движком):
Регулярное выражение: \{\{(if)\}\}(((?!\{\{\/?\1\}\})[\s\S])*(\{\{\1\}\}(?2)*\{\{\/\1\}\})*((?!\{\{\/?\1\}\})[\s\S])*)\{\{\/\1\}\}
EDIT 3: я удалил обязательство поддерживать TAG без его окончания. Я переформатировал вопрос для пользователей futur, чтобы понять некоторые комментарии ниже, см. Первую версию сообщения
Более того, у меня есть работа для всех трех одновременно, давая мне три матча, которые не работают на веб-сайте regex101. Разрыв линии должен поддерживаться в матче. Хотя, я мог бы согласиться, что только последние два в сочетании дают два матча, потому что я могу изменить тег один, if
для iif
.
Мое другое решение не использует регулярные выражения, но я хотел бы сделать это, если это возможно.
Вы можете использовать
~{{ # Opening tag start (\w+) # (Group 1) Tag name \^ # Aux delimiter ([^^\{\}]?) # (Group 2) Specific delimiter \^ # Aux delimiter ([^\{\}]+) # (Group 3) Parameters }} # Opening tag end ( # (Group 4) (?> (?R) # Repeat the whole pattern | # or match all that is not the opening/closing tag [^{]*(?:\{(?!{/?\1[^\{\}]*}})[^{]*)* )* # Zero or more times ) {{/\1}} # Closing tag ~ix
См. Демо-версию regex
В общем, выражение основано на рекурсии и умеренном жадном токене . Часть [^{]*(?:\{(?!{/?\1[^\{\}]*}})[^{]*)*
является развернутой (?s:(?!{{/?\1}}).)*
{{TAG}}
) .
)*, который соответствует любому символу ( .
), (?s:(?!{{/?\1}}).)*
не является отправной точкой для последовательностей символов {{TAG}}
или {{/TAG}}
.
Вам не нужен модификатор DOTALL для этого шаблона, поскольку его нет .
в шаблоне.
Вот демо-версия PHP :
$re = '~{{(\w+)\^([^^\{\}]?)\^([^\{\}]+)}}((?>(?R)|[^{]*(?:\{(?!{/?\1[^\{\}]*}})[^{]*)*)*){{/\1}}~i'; $str = "before {{if^^p1^p2}} IN1; {{if^ ^p1}} {{iif}} IN3 {{/if}} IN1-1 {{/if}} after\nbefore {{if^ ^p1}} IN1; {{if^ ^p1}} {{if^ ^p1}} IN3 {{/if}} {{/if}} IN1-1 {{/if}} after\nbefore {{if^ ^p1}} IN1; {{if^ ^p1}} {{if^ ^p1}} IN3 {{/if}} {{/if}} IN1-1 {{if^ ^p1}} IN4 {{/if}} {{/if}} after"; preg_match_all($re, $str, $matches); print_r($matches);