【问题标题】:php preg_replace using captured group as array indexphp preg_replace 使用捕获的组作为数组索引
【发布时间】:2016-07-18 20:48:01
【问题描述】:

看起来这应该很简单,但以下代码不起作用:

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

该代码应该在文本中查找所有实例,如“test1”、“test2”、“test3”等,并替换为 $array[1]、$array[2]、$array[ 3]等。

我做错了什么?

【问题讨论】:

  • 您想使用preg_replace_callback() 并通过use() 将数组传递给它,
  • preg_replace 的第二个参数接受一个替换字符串,它可以包含 $n 形式的引用。这些不是 php 变量,所以你不能以你想要的方式使用它们。

标签: php arrays regex


【解决方案1】:

你需要使用回调:

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

该函数获取匹配项并使用与数组项连接的第一个捕获组匹配项,第二个捕获组匹配项作为索引。您可能需要一个 if 来检查 $array[$m[2]] 是否首先存在。

您也可以使用循环:

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

【讨论】:

  • 谢谢!太棒了!
  • 我不知道发生了什么。您能否解释一下$m 的用途以及$m[1].$array[$m[2]] 的含义?
  • $m 是匹配的数组,因此 $m[1] 是来自第一个捕获组的匹配 ()
【解决方案2】:

你已经有了答案。这只是为了比在 cmets 中更好地解释您的假设错误。

$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

如你所见,first 参数被求值,then 结果被preg_replace 使用:test() 函数接收字面意思是$1(在与您的数组相同),而不是preg_replace 检索到的8;然后 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);

最后的文字是:

Lorem Ipsum Dolor

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

【讨论】:

    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 2021-02-13
    • 1970-01-01
    • 2014-04-29
    相关资源
    最近更新 更多