带有变量值的PHP preg_replace,使用找到的表达式作为键

时间:2016-02-10 14:50:37

标签: php arrays regex

我有一个字符串$src,其中包含两个可变占位符%%itemA%%%%itemB%%。我们的想法是使正则表达式匹配列出ITEMA|ITEMB|ITEMC的任何术语,不区分大小写,并使用术语作为数组键将术语替换为数组项的值。

$replacements = [
    'itemA' => 'replacedItemA',
    'itemB' => 'replacedItemB',
    'itemC' => 'replacedItemC'
];

$src = "A B C %%itemA%% D E F %%itemB%% G H I";

$src = preg_replace('/\%\%(ITEMA|ITEMB|ITEMC)%%/i', $replacements['\1'], $src);

echo $src;

在此示例中,预期结果是%%itemA%%替换为$replacements['itemA']的值,%%itemB%%替换为$replacements['itemB']的值

echo的预期输出

  

A B C replacementItemA D E F replacementItemB G H I

奇怪的是,实际输出只是简单地将所找到的项替换为空(注意删除变量的双空格)

  

A B C D E F G H I

为什么$replacements['key']中没有使用术语的字符串来使用数组变量的值?

2 个答案:

答案 0 :(得分:2)

你的做法是错误的。由于您正在处理文字字符串,因此可以避免使用正则表达式并使用更快的方法:

$replacements = [
    '%%itemA%%' => 'replacedItemA',
    '%%itemB%%' => 'replacedItemB',
    '%%itemC%%' => 'replacedItemC'
];

$str = strtr($str, $replacements);

答案 1 :(得分:0)

您只需将preg_replace替换为preg_replace_callback,就像这样:

$src = preg_replace_callback('/%%(ITEM[ABC])%%/i', function ($m) use ($replacements) {
 return isset($replacements[$m[1]]) ? $replacements[$m[1]] : $m[0];
}
, $src);

请参阅IDEONE demo

问题是\1反向引用只能在模式中用于引用第一个捕获组或替换模式内捕获的文本,但仅作为文本的一部分。 \1不会自动评估为用作参数。

我还略微收缩了这个模式,但我想这只是一个样本。