这是一个棘手的问题,我正在尝试做的事情:
$str="abc def abc";
我想将first
abc
次123
次出现second
abc
次出现456
preg_replace('/abc/', '123', $str, 1);
现在有了preg_match,我可能会将第一次出现的abc替换成123这样的
{{1}}
但是如何用456替换第二次出现,最重要的是如何一次性更换并生成所需的字符串(即123 def 456)。
注意:字符串是从外部源生成的。
感谢艾哈迈尔
答案 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_callback
与closure
一起用作回调(适用于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);