【问题标题】:PHP Replace 1st occurrence with x and 2nd occurrence of string with yPHP 用 x 替换第 1 次出现,用 y 替换第 2 次出现的字符串
【发布时间】:2014-03-07 13:28:41
【问题描述】:

这是一个棘手的问题,这是我想要做的:

$str="abc def abc";

我想用123 替换first 出现的abcsecond 出现的abc456 现在有了 preg_match,我可以像这样用 123 替换第一次出现的 abc

preg_replace('/abc/', '123', $str, 1);

但是如何用 456 替换第二个匹配项,最重要的是如何立即执行并生成所需的字符串(即 123 def 456)。

注意:字符串是从外部源生成的。

谢谢阿马尔

【问题讨论】:

  • 除了preg_replace('/abc/', '123', $str, 1); preg_replace('/abc/', '456', $str, 1);...preg_replace_callback()还有一个回调,它维护每个替换的静态计数,并可以根据该计数修改其响应

标签: php regex string


【解决方案1】:

你们很亲密:

$str = preg_replace('/abc/', '123', $str, 1); // will replace first 'abc'
$str = preg_replace('/abc/', '456', $str);    // will replace all others

之所以会这样,是因为第二个正则表达式的第一次出现,实际上是第二个项目。
Pro:非常易读,非常容易理解和实现
缺点:字符串将被正则表达式两次(对大字符串不利),选项有限


如果这不是你想要的,你可以使用preg_replace_callback()

$firstHasBeenFound = false;
function magicFunction($matches){
    global $firstHasBeenFound;
    print_r($matches);
    if( !$firstHasBeenFound ){
        /* do something for the first time */ ;
        $firstHasBeenFound = true; // save for next round
    }
    else{
         /* do something for the test */ ;
    }
}

$str = preg_replace_callback('/abc/', 'magicFunction', $str);

Pro:可以制作更多变体,对代码进行更多控制,只解析一次字符串
Con:更难阅读/实现

在本例中,我使用$firstHasBeenFound,但您可以使用增量每 2 次执行某项操作,或者在找到匹配 7 时执行某项操作,等等

【讨论】:

  • Err...当preg_replace_callback 存在时为什么要使用hack?
  • $firstHasBeenFound 变量在您的函数中将不可用,因此这不起作用。您必须使用闭包(请参阅 Mark 的回答)或使用 global(无论如何这不是一个好习惯)来实现这一点。
【解决方案2】:

这个怎么样?

$str = preg_replace('/abc(.*?)abc/', '123${1}456', $str, 1);

【讨论】:

  • 我喜欢这个想法,但是当你使用更大的正则表达式时,这会导致混乱。但是对于小型替代品,这将是很棒的
  • @Martijn 是的,可能会。因为它将需要将组保持在 1 美元,并且在最坏的情况下会很重!
【解决方案3】:
$str="abc def abc ghi abc";
$replacements = array('123', '456');

$str = preg_replace_callback(
    '/abc/',
    function ($matches) use ($replacements) {
        static $counter = 0;
        $returnValue = $matches[0];
        if (isset($replacements[$counter]))
            $returnValue = $replacements[$counter];
        $counter++;
        return $returnValue;
    },
    $str
);

var_dump($str);

【讨论】:

    【解决方案4】:

    您可以使用 preg_replace_callbackclosure 作为回调(适用于 PHP 5.3+)。

    $str = "abc def abc abc def abc";
    $a_replc = array('123', '456');
    $n = 0;
    $str = preg_replace_callback('/abc/', function () use (&$n, $a_replc) {
        return $a_replc[$n++ % count($a_replc)];
    }, $str);
    

    【讨论】:

      猜你喜欢
      • 2022-10-07
      • 1970-01-01
      • 2011-08-25
      • 2018-08-11
      • 2016-11-02
      • 2011-06-05
      • 2018-03-24
      相关资源
      最近更新 更多