将preg_replace转换为preg_replace_match以查找并用变量替换单词

时间:2018-12-20 17:47:29

标签: php regex preg-replace preg-replace-callback

我有以下代码行:

$message = preg_replace('/\{\{([a-zA-Z_-]+)\}\}/e', "$$1", $body);

这将用相同名称的变量替换被两个大括号括起来的单词。即{{username}}被$ username代替。

我正在尝试将其转换为使用preg_replace_callback。到目前为止,这是我基于Googling的代码,但我不确定自己在做什么! error_log输出显示变量名称,包括大括号。

$message = preg_replace_callback(
    "/\{\{([a-zA-Z_-]+)\}\}/",
        function($match){
            error_log($match[0]);
            return $$match[0];
        },
        $body
);

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:2)

在PHP中,函数具有自己的变量范围,因此,除非您明确指定,否则要替换的任何内容在函数内均不可用。我建议将替换项放置在数组中,而不要放置在单个变量中。这有两个优点-首先,它使您可以轻松地将它们放入函数范围内;其次,它提供了内置的白名单机制,因此您的模板不会偶然(或故意)引用不应被引用的变量。暴露的。

// Don't do this:
$foo = 'FOO';
$bar = 'BAR';

// Instead do this:
$replacements = [
    'foo' => 'FOO',
    'bar' => 'BAR',
];

// Now, only things inside the $replacements array can be replaced.

$template = 'this {{foo}} is a {{bar}} and here is {{baz}}';
$message = preg_replace_callback(
    '/\{\{([a-zA-Z_-]+)\}\}/',
    function($match) use ($replacements) {
        return $replacements[$match[1]] ?? '__ERROR__';
    },
    $template
);

echo "$message\n";

这将产生:

this FOO is a BAR and here is __ERROR__