#php #regex
#php #регулярное выражение
Вопрос:
До сих пор мне успешно удавалось избегать очень многого с регулярными выражениями, кроме проверки правильности адреса электронной почты. Однако, как часть более крупного университетского проекта, я разрабатываю простой движок tempting и пытаюсь реализовать свой собственный простой синтаксис для обработки циклов и, в конечном итоге, операторов IF вместо включения PHP в мои файлы шаблонов. Я знаю, что многие люди скажут, не беспокойтесь или просто используйте существующую систему, но поскольку это для моей диссертации, я хочу, чтобы как можно больше из этого было моей собственной работой!
В любом случае, вернемся к проблеме. В качестве примера у меня есть следующий код в файле моего шаблона:
<p>Template Header</p>
{{foreach{array1}}}
<p>This is the first content line that should be displayed.</p>
{{/foreach}}
{{foreach{array2}}}
<p>This is the second content line that should be displayed.</p>
{{/foreach}}
<p>Template Footer</p>
Затем я получил следующий PHP для чтения файла, поиска циклов и их извлечения.
<?php
$template = file_get_contents('reg.html');
$expression = "#.*{{foreach{(.*?)}}}(.*?){{/foreach}}.*#is";
$result = preg_replace($expression, "$1", $template);
var_dump($result);
?>
При вызове preg_replace и выгрузке результата $ 1 дает мне имя массива, которое будет использоваться для цикла (array1 или array2), затем изменение его на $ 2 даст мне содержимое между тегами цикла. Идеальный. Проблема в том, что это работает только для одного тега {{foreach}}.
Могу ли я в любом случае зациклить все совпадения регулярного выражения, чтобы получить результаты, которые я получаю выше? Любая помощь / совет очень ценится — но go easy regex для меня довольно новое!
Комментарии:
1. Это неподходящая задача для регулярных выражений. У вас будет жестокое время, как только вы попытаетесь вложить
foreach
илиif
заблокировать. Вам нужно написать настоящий синтаксический анализатор, а не собирать что-то вместе, злоупотребляя регулярными выражениями.
Ответ №1:
$expression = "#.*{{foreach{(.*?)}}}(.*?){{/foreach}}.*#is";
^^ ^^
Вы не просто сопоставляете тег шаблона «foreach», но и все, что до и после него. Это означает, что второй foreach тоже будет поглощен .*
. Таким образом, вы не можете сопоставить его снова.
Комментарии:
1. Вы можете добавить, что, в частности, совпадение будет соответствовать всей строке, если она содержит один из этих
foreach
блоков, а затем заменить всю строку содержимымforeach
блока. То есть заменяется , а не просто съедается.