Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中创建模板处理程序(负面前瞻问题)_Php_Regex_Template Engine - Fatal编程技术网

在PHP中创建模板处理程序(负面前瞻问题)

在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*} 问题是,由于变量替换

我正在用PHP开发一个像smarty这样的小模板处理程序,只是一个简单得多的处理程序。我以前用过smarty,但它对我来说太结实了。我以为我已经准备好了,但是一个非常讨厌的错误出现了。 我的想法很简单。我使用preg_split来分离模板命令和html代码、进程和内爆。{foreach}命令工作得很好,所以我根本就不打算执行它,错误出现在{if}子句中。 regexp的“{if}部分”是:

{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}'}
    )
)