PHP preg_match_all: теги скобок внутри тегов скобок

У меня есть свои пользовательские теги, например.

{{tag-name}}
<table>
  <tr>
    {{loop}}<td>text</td> ... {{/loop}}
  </tr>
</table>
{{/tag-name}}

Я хочу извлечь HTML-код внутри тегов скобок.

Я использую этот шаблон в preg_match_all:

/{\{.*?\}\}((?:(?!\{\{/(.*?)\}\}).)*)\{\{\/.*?\}\}/s

но это не работает. Как я могу это исправить?


person Paul K.    schedule 11.04.2014    source источник
comment
Как должен выглядеть извлеченный текст?   -  person sshashank124    schedule 11.04.2014
comment
Вы хотите выполнить замену после совпавшего контента? Я спрашиваю об этом, потому что если да, то подход может быть другим.   -  person Casimir et Hippolyte    schedule 11.04.2014
comment
Что означает выражение «не работает»? «Не работает» — это неадекватное описание для понимания проблемы. Что произошло, когда вы попробовали это? Вы получили сообщение об ошибке? Вы получили неправильные результаты? Вы получили нет результатов? Если результаты были неверными, что сделало их неверными? Что вы ожидали вместо этого? Вы получили любые правильные результаты? Если да, то какие? Не заставляйте нас гадать.   -  person Andy Lester    schedule 11.04.2014
comment
@sshashank124, например: pastebin.com/whJ2dnMh   -  person Paul K.    schedule 11.04.2014
comment
@AndyLester, вот что я получаю: regex101.com/r/nX2tY2   -  person Paul K.    schedule 11.04.2014
comment
@CasimiretHippolyte, когда preg_match_all найдет тег внутри тега, я хочу заменить его циклом php.   -  person Paul K.    schedule 11.04.2014
comment
ПОЖАЛУЙСТА, не анализируйте html с помощью регулярных выражений! stackoverflow.com/questions/1732348/   -  person MarcoS    schedule 11.04.2014


Ответы (2)


получить теги вашего отца с помощью preg_match_all и "/\{\{.[^\}]+\}\}(.+)\{\{\/.+\}\}/s" regex; проблема в том, что ваш тег находится внутри другого тега.

Посмотрите DomDocument по адресу http://php.net/manual/en/class.domdocument.php позволяет легко загрузить документ, получить теги внутри документа и пометить содержимое с помощью простого вызова метода...

person Thiago França    schedule 11.04.2014

Если {{tag-name}} не является произвольным вложенным, это регулярное выражение должно сделать это:

$pattern = '~{{([^}]+)}}(.*?){{/\1}}~s';

См. на regex101.com

Захватывает имя тега в первой группе в скобках {{([^}]+)}} и соответствует концу {{/\1}}

Захваченные матчи 2-й группы в скобках (.*?) будут в $out[2]

Использование s (PCRE_DOTALL) модификатора и *? ленивый квантификатор.


Используйте с preg_match или preg_match_all при желании, например

if(preg_match_all($pattern, $input, $out)) {
   var_dump($out);
}

См. пример на eval.in.

person Jonny 5    schedule 11.04.2014