Шаблон с использованием регулярных выражений - PullRequest
0 голосов
/ 23 декабря 2008

Привет всем, я работаю над приложением PHP, которому нужно проанализировать файл .tpl с HTML в нем, и я делаю так, чтобы в HTML могли быть переменные и базовые операторы if. Выражение if выглядит примерно так: `

<!--if({VERSION} == 2)-->
Hello World
<!--endif -->

Чтобы разобрать это, я попытался использовать preg_replace, но безуспешно. Шаблон, который я пробовал, был

/<!--if\(([^\]*)\)-->([^<]*)<!--endif-->/e

который заменяется на

if($1) { echo "$2"; }

Есть идеи, почему это не сработает, и что я могу сделать, чтобы запустить его?

Ответы [ 3 ]

3 голосов
/ 23 декабря 2008

У вас есть пробел между endif и -->, но ваше регулярное выражение не позволяет этого.

Кстати, это кажется ужасно ненадежным ... Есть ли какая-то причина, по которой вы не используете встроенный шаблонизатор, такой как Smarty?

2 голосов
/ 23 декабря 2008

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

'/<!--if\(([^\\\]*)\)-->([^<]*)<!--endif-->/e'

Но я не знаю, почему вы изобретаете новую логику шаблонов, когда существуют такие решения, как Smarty и сам PHP.


Вот тестовый код в ответ на комментарии ниже.

testinput.tpl

<!--if({VERSION} == 2)-->
Hello World
<!--endif-->

match.php

<?php
$template = file_get_contents('testinput.tpl');
print preg_match('/<!--if\(([^\\\]*)\)-->/e', $template) . "\n";
print preg_match('/<!--endif-->/e', $template) . "\n";
print preg_match('/<!--if\(([^\\\]*)\)-->([^<]*)<!--endif-->/e', $template) . "\n";

тестовый прогон :

$ php match.php
1
1
1
0 голосов
/ 24 декабря 2008

Я думаю, вы хотели это сделать:

'/<!--if\(([^)]*)\)-->([^<]*)<!--endif-->/'

В вашем регулярном выражении есть только один класс символов:

[^\]*)\)-->([^<]

Вот что происходит:

  • Первая закрывающая квадратная скобка экранирована обратной косой чертой, поэтому она соответствует буквально.
  • Скобки, которые должны были закрыть первую группу захвата и открыть вторую, также воспринимаются буквально; нет необходимости избегать паренов внутри класса персонажа.
  • Первый дефис - это , взятый как метасимвол; он формирует диапазон [) * +, -]
  • Вторая открывающая квадратная скобка принимается за буквальную квадратную скобку, поскольку она находится внутри класса символов.
  • Вторая каретка считается буквальной, потому что это не первый персонаж в классе.

Итак, после удаления дубликатов и сортировки символов в порядке ASCII ваш класс символов эквивалентен следующему:

[^()*+,\-<>\[\]^]

И круглые скобки вне класса символов по-прежнему сбалансированы, поэтому регулярное выражение компилируется, но даже близко не соответствует тому, что вы хотели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...