带有正则表达式的PHP模板引擎中的多if
首先,很抱歉我的英语很差 我正在尝试使用regex&preg\u match\u all创建一个PHP模板引擎 我的正则表达式看起来像:带有正则表达式的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]*?
/\{:[\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你有什么例子或其他的吗?我真的不知道没有正则表达式怎么做。非常感谢。这里的所有内容都必须是英语。