在PHP中创建模板处理程序(负面前瞻问题)
我正在用PHP开发一个像smarty这样的小模板处理程序,只是一个简单得多的处理程序。我以前用过smarty,但它对我来说太结实了。我以为我已经准备好了,但是一个非常讨厌的错误出现了。 我的想法很简单。我使用preg_split来分离模板命令和html代码、进程和内爆。{foreach}命令工作得很好,所以我根本就不打算执行它,错误出现在{if}子句中。 regexp的“{if}部分”是:在PHP中创建模板处理程序(负面前瞻问题),php,regex,template-engine,Php,Regex,Template Engine,我正在用PHP开发一个像smarty这样的小模板处理程序,只是一个简单得多的处理程序。我以前用过smarty,但它对我来说太结实了。我以为我已经准备好了,但是一个非常讨厌的错误出现了。 我的想法很简单。我使用preg_split来分离模板命令和html代码、进程和内爆。{foreach}命令工作得很好,所以我根本就不打算执行它,错误出现在{if}子句中。 regexp的“{if}部分”是: {if\s+[a-zA-Z0-9\{'\}\=\s\/$\!\=]{1,}\s*} 问题是,由于变量替换
{if\s+[a-zA-Z0-9\{'\}\=\s\/$\!\=]{1,}\s*}
问题是,由于变量替换,我必须允许使用花括号,这会导致regexp不停在“{if**}”的末尾。我试着用消极的表情和否定积极的表情来排除“{if”来避免这个问题,但是我没有运气
模板的一个示例:
{if '{$a}' = 'a'}
blabla
{if 'c' = 'c'}
blabla
{/if}
{/if}
valami más
{if 'b' != 'b'}
blabla
{/if}
{if '{$c}' = '{$c}'}
blabla
{/if}
预期输出:{if '{$a}' = 'a'}
{if 'c' = 'c'}
{if 'b' != 'b'}
{if '{$c}' = '{$c}'}
有人能帮忙吗?根据您上面的描述,我创建了以下正则表达式。我希望这就是您要找的
<?php
$string = <<<'EOD'
{if '{$a}' = 'a'}
blabla
{if 'c' = 'c'}
blabla
{/if}
{/if}
valami más
{if 'b' != 'b'}
blabla
{/if}
{if '{$c}' = '{$c}'}
blabla
{/if}
EOD;
$pattern = "~{if\s+'(?:\\{\\$(?:[A-Za-z0-9]+\\})|(?:[A-Za-z0-9]))'\s+(?:=|(?:!=))\s+'(?:(?:\\{\\$(?:[A-Za-z0-9]+\\}))|(?:[A-Za-z0-9]))'\\}~";
preg_match_all($pattern, $string, $matches);
echo '<pre>'.print_r($matches,1).'</pre>';
?>
)
更新的答案
考虑到下面的注释,我创建了下面的正则表达式。我承认这并不是最好的解决方案,但它允许使用诸如{if'{$c}'='{$c}'&&&{$b}'='{$b}'之类的参数
。您可以简单地复制模式,以便在一个if
语句中允许两个以上的表达式。显然,它将增长到一个荒谬的长度!但是,如果这是用于模板引擎,可能不需要太多扩展?所需的任何其他运算符也可以简单地添加到ap的正则表达式中合适的地方
再一次,我意识到这不是解决问题的最佳方法;很抱歉,我自己无法创建递归版本。也许其他人也可以这样做
$string = <<<'EOD'
{if '{$a}' = 'a'}
blabla
{if 'c' = 'c'}
blabla
{/if}
{/if}
valami más
{if 'b' != 'b'}
blabla
{/if}
{if '{$c}' = '{$c}'}
blabla
{/if}
{if '{$c}' = '{$c}' && '{$b}' = '{$b}'}
EOD;
如果你是为自己做这件事,那就不用麻烦了,我推荐你PIP,它很小也很好。离题了,你只是重新发明了一个轮子,那里有这么多免费的php模板引擎!!!这听起来很迂腐,但php本身就是一个模板引擎。为什么还要在上面再加一个呢?首先,感谢你的回复。我这是一个不错的解决方案,但我第一次没有写的是,我不仅希望“==”和“!=”操作符可以工作,而且每隔一个,所以“&&”和“| |”和"我会建议一个修改过的正则表达式,这会很冗长,但它似乎能起作用。我会马上用它更新我的答案。不过,我很想看看其他人是如何解决这个问题的;我认为这里需要一个递归调用,但我还没能完成这项工作,因为我对正则表达式不太熟悉!再次感谢你的回答n、 我一直主张完美,但我认为你的解决方案可以处理99%的情况。不过,我希望有其他解决方案。我想我会等一周,如果没有其他解决方案,那么你将获胜:)
$pattern = "~{if\s+(?:(?:'(?:\\{\\$(?:[A-Za-z0-9]+\\})|(?:[A-Za-z0-9]))'\s+(?:=|(?:!=)|(?:==)|(?:<=)|(?:>=))\s+'(?:(?:\\{\\$(?:[A-Za-z0-9]+\\}))|(?:[A-Za-z0-9]))')(?:(?:\s+(?:&&|\\|\\|)\s+)(?:'(?:\\{\\$(?:[A-Za-z0-9]+\\})|(?:[A-Za-z0-9]))'\s+(?:=|(?:!=)|(?:==)|(?:<=)|(?:>=))\s+'(?:(?:\\{\\$(?:[A-Za-z0-9]+\\}))|(?:[A-Za-z0-9]))'))?)\\}~";
$string = <<<'EOD'
{if '{$a}' = 'a'}
blabla
{if 'c' = 'c'}
blabla
{/if}
{/if}
valami más
{if 'b' != 'b'}
blabla
{/if}
{if '{$c}' = '{$c}'}
blabla
{/if}
{if '{$c}' = '{$c}' && '{$b}' = '{$b}'}
EOD;
Array
(
[0] => Array
(
[0] => {if '{$a}' = 'a'}
[1] => {if 'c' = 'c'}
[2] => {if 'b' != 'b'}
[3] => {if '{$c}' = '{$c}'}
[4] => {if '{$c}' = '{$c}' && '{$b}' = '{$b}'}
)
)