PHP将第一次出现替换为x,将第二次出现的字符串替换为y

时间:2014-03-07 13:28:41

标签: php regex string

这是一个棘手的问题,我正在尝试做的事情:

$str="abc def abc";

我想将first abc123次出现second abc次出现456 preg_replace('/abc/', '123', $str, 1); 现在有了preg_match,我可能会将第一次出现的abc替换成123这样的

{{1}}

但是如何用456替换第二次出现,最重要的是如何一次性更换并生成所需的字符串(即123 def 456)。

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

感谢艾哈迈尔

4 个答案:

答案 0 :(得分:6)

你非常接近:

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

这样做的原因,是因为第二个正则表达式的第一个出现,实际上是第二个项目。
Pro :非常易读,易于理解和实施 Con :字符串将被重复两次(大字符串不好),选项有限


如果这不是您想要的,可以使用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);

专业:可以制作更多变种,更多地控制代码,只需对字符串进行一次解析
Con :更难阅读/实施

在这个例子中,我使用$firstHasBeenFound,但是你可以使用增量来做每个第二个的东西,或者当你找到匹配7时做某事等等。

答案 1 :(得分:2)

这个怎么样?:

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

答案 2 :(得分:0)

$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);

答案 3 :(得分:0)

您可以将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);