Php preg_更换不正确

Php preg_更换不正确,php,regex,templates,preg-replace,Php,Regex,Templates,Preg Replace,我从一位朋友那里得到了一些帮助(他现在外出度假),但我在preg\u replacesearch and replace方面遇到了问题。我不知道为什么,但它正在错误地替换字符串,这对它应该替换的下一个字符串产生了连锁反应 这基本上是在模板类中处理模板中的“if”和“else”查询 function if_statement($a, $b, $if, $type, $else = NULL){ if($type == "1" && is_numeric($a) &&

我从一位朋友那里得到了一些帮助(他现在外出度假),但我在
preg\u replace
search and replace方面遇到了问题。我不知道为什么,但它正在错误地替换字符串,这对它应该替换的下一个字符串产生了连锁反应

这基本上是在模板类中处理模板中的“if”和“else”查询

function if_statement($a, $b, $if, $type, $else = NULL){
    if($type == "1" && is_numeric($a) && is_numeric($b)){
        $statement = ($a === $b) ? $if : $else;
    } else if($type == "1"){
        $statement = ($a == $b) ? $if : $else;
    } else if($type == "2"){
        $statement = ($a != $b) ? $if : $else;
    }
    return stripslashes($statement);
}

$output = file_get_contents("template.tpl");

$replace = array(
  '#\<if:"\'(.*?)\' == \'(.*?)\'"\>(.*?)\<else\>(.*?)\<\/endif\>#sei',
  '#\<if:"\'(.*?)\' == \'(.*?)\'"\>(.*?)\<\/endif\>#sei'
);  
$functions = array(
  "if_statement('\\1', '\\2', '\\3', '1', '\\4')",
  "if_statement('\\1', '\\2', '\\3', '1')"
);
$output = preg_replace($replace, $functions, $output);
echo $output;
函数if_语句($a,$b,$if,$type,$else=NULL){ 如果($type==“1”&&is\u numeric($a)&&is\u numeric($b)){ $statement=($a===$b)?$if:$else; }else if($type==“1”){ $statement=($a==$b)?$if:$else; }else if($type==“2”){ $statement=($a!=$b)?$if:$else; } 返回斜杠($statement); } $output=文件获取内容(“template.tpl”); $replace=数组( “#\(.*?)\(.*?\#sei”, “#\(.*)\#sei” ); $functions=数组( “如果_语句('\\1'、'\\2'、'\\3'、'\\1'、'\\4')”, if_语句('\\1','\\2','\\3',1')” ); $output=preg_replace($replace,$functions,$output); echo$输出; 模板:

<HTML>
    <head>
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
    <title>Site Title</title>
    <link rel="stylesheet" type="text/css" media="screen" href="common.css" />
    <if:"'{ISADMIN}' == '1'">
        <link rel="stylesheet" href="admin-bar.css" type="text/css" media="all" />
    </endif>
</head>
<body>
    <if:"'{TODAY}' == 'Monday'">Today is Monday<else>Today is not Monday</endif>
    <if:"'1' == '2'">1 equals 2!<else>1 doesn't equal 2</endif>
</body>
</html>

网站名称
今天是星期一今天不是星期一
1等于2!1不等于2
其中,电流输出将低于:

<HTML>
    <head>
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
    <title>Site Title</title>
    <link rel="stylesheet" type="text/css" media="screen" href="common.css" />

        <link rel="stylesheet" href="admin-bar.css" type="text/css" media="all" />
    **</endif>**
</head>
<body>
    **<if:"'{TODAY}' == 'Monday'">**Today is Monday
    1 doesn't equal 2
</body>
</html>

网站名称
****
****今天是星期一
1不等于2
在上面,粗体/astrix makred部分不应该出现在输出中,而且今天也不是星期一。当管理员登录时,
admin bar.css
文件被正确地包括在内,但由于某种原因,它没有拾取
标记-事实上,它看起来像是在下一个语句中跟随了
标记。。。换句话说,
preg\u replace
匹配了一个不正确的东西!因此,在第二条
语句中没有提到

{BRACKET}
标记被正确替换-我甚至已经手动将数据放入语句中(只是为了检查),所以它们不是问题所在

我不知道为什么,但对我来说,
preg\u replace
没有找到正确的顺序来替换和执行。如果有人能给我一双新眼睛/伸出援助之手,我将不胜感激

谢谢

示例中的第一个
没有
子句。因此,当对其应用
(.*)(.*)
(其中
不是可选的)时,它匹配所有这些:

    <if:"'{ISADMIN}' == '1'">
        <link rel="stylesheet" href="admin-bar.css" type="text/css" media="all" />
    </endif>
</head>
<body>
    <if:"'{TODAY}' == 'Monday'">Today is Monday<else>Today is not Monday</endif>
您可以通过使用前瞻断言禁止正则表达式跨越
来避免这种情况:

'%<if:\s*"\'([^\']*)\' == \'([^\']*)\'">((?:(?!<else>|</endif>).)*)<else>((?:(?!</endif).)*)</endif>%si'
“%((?:(?!))*)((?:)?!
(#进入第3组:
(?:#以下小组。。。
(?!#除非我们在。。。
# 
|#或
# 
)#(前瞻断言结束)
.#匹配任意字符
)*#必要时重复
)#第3组捕获结束
#匹配
(#与上述结构相同,第4组
(?:
(?!
#这一次只是寻找
)
.
)*
)
#最后是比赛
%esix'
第二个正则表达式也应该改进:

'%<if:\s*"\'     # Match <if:(optional space)"\'
    ([^\']*)     # Match 0 or more non-quote characters, capture group 1
    \'\s==\s\'   # Match \' == \'
    ([^\']*)     # Match 0 or more non-quote characters, capture group 2
    \'">         # Match \'">
    (            # Capture into group 3:
     (?:
      (?!
       </endif>  # Any text until </endif>
      )
      .
     )*
    )
    </endif>     # and finally match </endif>
    %esix'
”%
(#进入第3组:
(?:
(?!
#任何文本,直到
)
.
)*
)
#最后是比赛
%esix'
此外,这些正则表达式应该更快,因为它们更清楚地指定了哪些可以匹配,哪些不可以匹配,从而避免了大量回溯。

示例中的第一个
没有
子句。因此,当
(.*)(.*)
(其中
不是可选的)应用于它时,它匹配所有这些:

    <if:"'{ISADMIN}' == '1'">
        <link rel="stylesheet" href="admin-bar.css" type="text/css" media="all" />
    </endif>
</head>
<body>
    <if:"'{TODAY}' == 'Monday'">Today is Monday<else>Today is not Monday</endif>
您可以通过使用前瞻断言禁止正则表达式跨越
来避免这种情况:

'%<if:\s*"\'([^\']*)\' == \'([^\']*)\'">((?:(?!<else>|</endif>).)*)<else>((?:(?!</endif).)*)</endif>%si'
“%((?:(?!))*)((?:)?!
(#进入第3组:
(?:#以下小组。。。
(?!#除非我们在。。。
# 
|#或
# 
)#(前瞻断言结束)
.#匹配任意字符
)*#必要时重复
)#第3组捕获结束
#匹配
(#与上述结构相同,第4组
(?:
(?!
#这一次只是寻找
)
.
)*
)
#最后是比赛
%esix'
第二个正则表达式也应该改进:

'%<if:\s*"\'     # Match <if:(optional space)"\'
    ([^\']*)     # Match 0 or more non-quote characters, capture group 1
    \'\s==\s\'   # Match \' == \'
    ([^\']*)     # Match 0 or more non-quote characters, capture group 2
    \'">         # Match \'">
    (            # Capture into group 3:
     (?:
      (?!
       </endif>  # Any text until </endif>
      )
      .
     )*
    )
    </endif>     # and finally match </endif>
    %esix'
”%
(#进入第3组:
(?:
(?!
#任何文本,直到
)
.
)*
)
#最后是比赛
%esix'

此外,这些正则表达式应该更快,因为它们更清楚地指定了哪些可以匹配,哪些不可以匹配,从而避免了大量的回溯。

感谢您的帮助和解释Tim!是否可以在初始
之后添加“空格检测”?感谢您的帮助和解释Tim!是否可以在in之后添加“空格检测”初始<代码>