Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.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模板引擎中的多if_Php_Regex_If Statement_Templates_Preg Match All - Fatal编程技术网

带有正则表达式的PHP模板引擎中的多if

带有正则表达式的PHP模板引擎中的多if,php,regex,if-statement,templates,preg-match-all,Php,Regex,If Statement,Templates,Preg Match All,首先,很抱歉我的英语很差 我正在尝试使用regex&preg\u match\u all创建一个PHP模板引擎 我的正则表达式看起来像: /\{:[\s]*?[\n]*?[\s]*?if(.*?):\}[\s]*?(.*?)[\s]*?(\{:[\s]?else[\s]?:\}[\s]*?(.*?)[\s]*?)\{:[\s]*?endif[\s]*?:\}/is preg_match_all('/\{:[\s]*?[\n]*?[\s]*?if(.*?):\}[\s]*?(.*?)[\s]*?

首先,很抱歉我的英语很差

我正在尝试使用regex&preg\u match\u all创建一个PHP模板引擎

我的正则表达式看起来像:

/\{:[\s]*?[\n]*?[\s]*?if(.*?):\}[\s]*?(.*?)[\s]*?(\{:[\s]?else[\s]?:\}[\s]*?(.*?)[\s]*?)\{:[\s]*?endif[\s]*?:\}/is
preg_match_all('/\{:[\s]*?[\n]*?[\s]*?if(.*?):\}[\s]*?(.*?)[\s]*?(\{:[\s]?else[\s]?:\}[\s]*?(.*?)[\s]*?)\{:[\s]*?endif[\s]*?:\}/is', $template, $regs, PREG_PATTERN_ORDER);


for ($i = 0, $iMax = count($regs[0]); $i < $iMax; $i++) {
    $condition = $regs[1][$i];
    $trueval   = $regs[2][$i];
    $falseval  = $regs[4][$i] ?? false;
    $res = eval('return ('.$condition.');');

    if ($res===true) {
        $template = str_replace($regs[0][$i],$trueval,$template);

    } else {
        $template = str_replace($regs[0][$i],$falseval,$template);
    }
}
我的PHP看起来像:

/\{:[\s]*?[\n]*?[\s]*?if(.*?):\}[\s]*?(.*?)[\s]*?(\{:[\s]?else[\s]?:\}[\s]*?(.*?)[\s]*?)\{:[\s]*?endif[\s]*?:\}/is
preg_match_all('/\{:[\s]*?[\n]*?[\s]*?if(.*?):\}[\s]*?(.*?)[\s]*?(\{:[\s]?else[\s]?:\}[\s]*?(.*?)[\s]*?)\{:[\s]*?endif[\s]*?:\}/is', $template, $regs, PREG_PATTERN_ORDER);


for ($i = 0, $iMax = count($regs[0]); $i < $iMax; $i++) {
    $condition = $regs[1][$i];
    $trueval   = $regs[2][$i];
    $falseval  = $regs[4][$i] ?? false;
    $res = eval('return ('.$condition.');');

    if ($res===true) {
        $template = str_replace($regs[0][$i],$trueval,$template);

    } else {
        $template = str_replace($regs[0][$i],$falseval,$template);
    }
}
preg\u match\u all('/\{:[\s]*?[\n]*?[\s]*?if(.*?:\}[\s]*?(.*?[\s]*?(\{:[\s]?else[\s]?:\}[\s]*?(.[\s]*?)\{:[\s]*?endif[\s]*?:\}/is',$template,$regs,preg\u模式顺序);
对于($i=0,$iMax=count($regs[0]);$i<$iMax;$i++){
$condition=$regs[1][$i];
$trueval=$regs[2][$i];
$falseval=$regs[4][$i]??false;
$res=eval('return('.$condition.');');
如果($res==true){
$template=str_replace($regs[0][$i],$trueval,$template);
}否则{
$template=str_replace($regs[0][$i],$false$template);
}
}
在我的模板字符串中,只有一个if,类似于:

{: if $var > 3 :}
    The variable $var is > than 3
{: else :}
    The variable $var is < than 3
{: endif :}
{:if$var>3:}
变量$var大于3
{:else:}
变量$var小于3
{:endif:}
它将完美地工作。但如果我在这里加上另一个if,它就不起作用了

{: if $var > 3 :}
    The variable $var is > than 3
    {: if $var1 < 2 :}
        The variable $var1 < than 2
    {: else :}
        The variable $var1 > than 2
    {: endif :}
{: else :}
    The variable $var is < than 3
{: endif :}
{:if$var>3:}
变量$var大于3
{:如果$var1<2:}
变量$var1小于2
{:else:}
变量$var1>大于2
{:endif:}
{:else:}
变量$var小于3
{:endif:}
在这种情况下,preg match all将无法正常工作,并将向我输出以下内容:

{: if $var > 3 :}
    The variable $var is > than 3
    {: if $var1 < 2 :}
        The variable $var1 is < than 2
    {: else :}
        The variable $var1 is > than 2
    {: endif :}
{:if$var>3:}
变量$var大于3
{:如果$var1<2:}
变量$var1小于2
{:else:}
变量$var1大于2
{:endif:}

它会停在第一个端点,而不是好的端点。我完全不知道怎么做。如果有人有主意?非常感谢您的时间和帮助

我找到了一个解决方案,没有使用任何正则表达式。我不知道这是否是最好的做法,但它奏效了

首先,我将文本逐行拆分:

$text = explode(PHP_EOL, $text);
接下来,我将讨论这个$text:

        $if = [];
    foreach ($test as $key => $line){
        if(StringUtils::contains($line, 'if') && (!StringUtils::contains($line, 'endif'))){
            $if[$key] = trim($line);
        }
    }
正如你们所看到的,我在本文中寻找一些if,我把它们放在一个数组中,用行号作为键

接下来,我执行最后一个foreach,检查条件,并替换所有:

        krsort($if);

    $var = 4;
    $var1 = 1;
    foreach ($if as $ifOffset => $ix){
        for($i = $ifOffset, $iMax = count($test); $i<$iMax; $i++){
            if(StringUtils::contains($test[$i], 'endif')){
                $content = StringUtils::getBetween($text, $test[$ifOffset], $test[$i]);
                $cond = trim(str_replace('if', '', StringUtils::getBetween($ix, '{:', ':}')));
                $res = eval('return ('.$cond.');');

                $ph = $test[$ifOffset].$content.$test[$i];

                if($res===true){
                    $text = str_replace($ph, $content, $text);
                }else{
                    $text = str_replace($ph, '', $text);
                }
                unset($if[$ifOffset]);
                break;
            }
        }
    }
我们到了

对于“StringUtils::contains”函数,您可以:

    public static function contains($text, ...$search){
    if(!empty($search)){
        foreach($search as $key => $value){
            if(strpos($text, $value) !== false){
                unset($search, $text, $key, $value);
                return true;
                break;
            }
        }
        unset($search, $text);
    }
    return false;
}

如果有人有一个更好的主意,为什么不呢,但它很管用

这回答了你的问题吗?不要将正则表达式用于此类工作。写你自己的解析器。@Toto你有什么例子或其他的吗?我真的不知道没有正则表达式怎么做。非常感谢。这里的所有内容都必须是英语。