php preg_replace使用捕获的组作为数组索引

时间:2016-03-30 17:31:24

标签: php arrays regex

似乎这应该是直截了当的,但以下代码不起作用:

$text = preg_replace('/test([0-9]+)/i', $array["$1"], $text);

代码应该在文本中找到所有实例,如'test1','test2','test3'等,并替换为$ array [1],$ array [2],$ array [的值3]等。

我做错了什么?

2 个答案:

答案 0 :(得分:5)

您需要使用回调:

$text = preg_replace_callback('/(test)([0-9]+)/i', 
                              function($m) use($array) { return $m[1].$array[$m[2]]; },
                              $text);

该函数接受匹配并使用与数组项连接的第一个捕获组匹配,并将第二个捕获组匹配作为索引。您可能希望在那里检查$array[$m[2]]是否存在。

或者你可以使用循环:

foreach($array as $key => $val) {
    $text = str_replace("test$key", "test$val", $text);
}

答案 1 :(得分:0)

你已经有了答案。这个只是为了解释你的假设错误。

$1不是第一个参数的结果,它是preg_replace本身使用的占位符。您的使用也会调用命令优先级。

换句话说,如果您尝试此代码:

$text = 'Lorem test8 Dolor';
function test( $arg ) { echo $arg.PHP_EOL; }
$text = preg_replace('/test([0-9]+)/i', test("$1"), $text);
echo $text;

您获得此输出:

$1
Lorem  Dolor

正如您所看到的,第一个参数被评估,然后结果由preg_replace使用:test()函数接收字面{{1 (和你的数组一样),而不是$1检索到的8;然后preg_replace用第二个参数中返回的值替换匹配的子字符串:在上面的情况下preg_replace不返回任何内容,所以替换是什么都没有。

使用此代码:

test()

结果字符串是:

function test() { return '[$1]'; }
$text = preg_replace('/test([0-9]+)/i', test(), $text);

因为Lorem [8] Dolor 返回test()[$1]可以使用它来执行替​​换。

在您的具体情况下,只有在您遇到类似这样的情况时才会进行替换:

preg_replace

最终文本是:

$array["$1"] = 'Ipsum';
$text = preg_replace('/test([0-9]+)/i', $array["$1"], $text);

这不是你想要的结果,但是 - 如前所述 - 你已经有了答案......