通过preg_replace的反向引用调用常量

时间:2012-10-16 19:49:01

标签: php regex

$so = file_get_contents(...) ;
$so = preg_replace("/\*([^*]+)\*/e", constant(\1), $so) ;

尝试用相同名称的常量替换星号之间的文本,但我不断得到 意想不到的T_LNUMBER。我写错了什么?我验证了$是否存在字符串,所有常量都存在,因为它们是纯文本。

我可能不会使用这个脚本,但我很好奇我搞砸了什么

5 个答案:

答案 0 :(得分:5)

尝试preg_replace_callback("/\*([^*]+)\*/e", create_function('$matches','return constant($matches[1]);'), $so)

我一直怀疑php中有匿名函数,但我从来没有使用它们。这是更好的:

preg_replace_callback("/\*([^*]+)\*/e", function($matches){
    return constant($matches[1]);
}, $so)

编辑:正如下面的评论所指出的,一旦使用回调,\ e修饰符是不必要的,因为我们不需要评估返回值中的任何代码。

答案 1 :(得分:1)

正确的方法是:

$so = preg_replace_callback("/\*([^*]+)\*/", function($m){return constant($m[1])}, $so);

你的constant(\1)在php中没有任何意义。

答案 2 :(得分:0)

您应该替换为$1\1更适合用于反向引用,正如您所说,但是在相同的正则表达式中。

答案 3 :(得分:0)

问题在于如何评估代码。

该行:

preg_replace("/\*([^*]+)\*/e", constant(\1), $so) ;

应该是:

$so = preg_replace("/\*([^*]+)\*/e", "constant('\\1')", $so) ;

您需要将传递给constant()的值括在引号中,以便将其视为字符串。此外,将第二个参数括在引号中,以便评估反向引用。

答案 4 :(得分:0)

T_LNUMBER引用您的变量。您不能命名以数字开头的变量。 php codex