PHP - 在preg_replace中使用带有file_exists的反向引用

时间:2014-02-14 19:35:29

标签: php preg-replace file-exists backreference

我正在尝试用其他文件中的内容替换包含文件中某些标签的内容:

$view = preg_replace('/{include ([[:alnum:]\.-]+)}/', ((file_exists('template/$1.html')) ? 'OK $1' : 'KO $1'), file_get_contents('myTemplateFile.tpl'));

我在{include file.ext}中获得的所有myTemplateFile.tpl引用都替换为KO file.ext而不是OK file.ext

但是,如果我硬编码file_exists('template/file.ext'),则会显示正确的字符串。

在我看来,在file_exists电话中未正确解析后方引用。

我做错了什么?

2 个答案:

答案 0 :(得分:1)

$view = preg_replace(
    '/{include ([[:alnum:]\.-]+)}/', 
    ((file_exists('template/$1.html')) ? 'OK $1' : 'KO $1'), 
    file_get_contents('myTemplateFile.tpl')
);

以上代码执行如下:

$contents = file_get_contents('myTemplateFile.tpl');

if ((file_exists('template/$1.html')) {
    $result = preg_replace('/{include ([[:alnum:]\.-]+)}/', 'OK $1', $contents);
} else {
    $result = preg_replace('/{include ([[:alnum:]\.-]+)}/', 'KO $1', $contents);
}

正如您所看到的,file_exists()调用是在<{strong> preg_replace()语句之前执行的。它正在检查文件"template/$1.html"是否存在,其中 $1是一个没有特殊含义的文字字符串。该文件不存在,else块(最初为'KO $1')将始终执行。

简而言之,您无法使用preg_replace()函数外部 preg_replace()函数的反向引用。解决方案是preg_replace_callback()

preg_replace_callback(
    '/{include ([[:alnum:]\.-]+)}/',
    function ($m) {
        return file_exists('template/'.$m[1].'html') ? 'OK '.$m[1]: 'KO '.$m[1];
    },
    file_get_contents('myTemplateFile.tpl')
);

另见:

答案 1 :(得分:1)

preg_replace('/{include ([[:alnum:]\.-]+)}/', ((file_exists('template/$1.html')) ? 'OK $1' : 'KO $1'), file_get_contents('myTemplateFile.tpl'))

首先执行file_exists('template/$1.html'),然后将OK $1KO $1(可能是后者)传递给preg_replace,然后替换所有匹配项。

您必须使用回调来完成此工作,而不是将file_exists作为参数调用:

preg_replace_callback(
    '/{include ([[:alnum:]\.-]+)}/',
    function (array $m) {
        return file_exists("template/$m[1].html") ? "OK $m[1]" : "KO $m[1]";
    },
    file_get_contents('myTemplateFile.tpl')
)