Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP用x替换第一次出现的字符串,用y替换第二次出现的字符串_Php_Regex_String - Fatal编程技术网

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

PHP用x替换第一次出现的字符串,用y替换第二次出现的字符串,php,regex,string,Php,Regex,String,这是一个棘手的问题,我想做的是: $str="abc def abc"; 我想用123替换abc的第一次出现,用456替换abc的第二次出现 现在有了preg_match,我可以用123替换第一次出现的abc,就像这样 preg_replace('/abc/', '123', $str, 1); 但是如何用456替换第二个匹配项,最重要的是如何立即执行并生成所需的字符串(即123 def 456) 注意:字符串是从外部源生成的 谢谢艾哈迈尔你非常接近: $str = preg_replace

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

$str="abc def abc";
我想用
123
替换
abc
第一次出现,用
456
替换
abc
第二次出现
现在有了preg_match,我可以用123替换第一次出现的abc,就像这样

preg_replace('/abc/', '123', $str, 1);
但是如何用456替换第二个匹配项,最重要的是如何立即执行并生成所需的字符串(即123 def 456)

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

谢谢艾哈迈尔

你非常接近:

$str = preg_replace('/abc/', '123', $str, 1); // will replace first 'abc'
$str = preg_replace('/abc/', '456', $str);    // will replace all others
这将起作用的原因是,第二个正则表达式的第一次出现实际上是第二项。
Pro:可读性强,易于理解和实施
Con:字符串将被重新执行两次(对大字符串不好),选项有限


如果这不是您想要的,您可以使用
preg\u replace\u callback()

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


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

$str = preg_replace('/abc/', '123', $str, 1); // will replace first 'abc'
$str = preg_replace('/abc/', '456', $str);    // will replace all others
这将起作用的原因是,第二个正则表达式的第一次出现实际上是第二项。
Pro:可读性强,易于理解和实施
Con:字符串将被重新执行两次(对大字符串不好),选项有限


如果这不是您想要的,您可以使用
preg\u replace\u callback()

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


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

$str = preg_replace('/abc(.*?)abc/', '123${1}456', $str, 1);
这个怎么样

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

您可以使用
preg\u replace\u callback
closure
作为回调(适用于PHP5.3+)


您可以使用
preg\u replace\u callback
closure
作为回调(适用于PHP5.3+)


除了
preg_替换('/abc/','123',$str,1);preg_替换('/abc/','456',$str,1)
preg_replace_callback()
使用一个回调函数,该回调函数维护每个替换函数的静态计数,并且可以基于该计数修改其响应,除了
preg_replace(“/abc/”,“123”,$str,1);preg_替换('/abc/','456',$str,1)
preg\u replace\u callback()
使用一个回调函数,该回调函数维护每个替换函数的静态计数,并可以基于该计数器修改其响应。。。如果存在
preg\u replace\u回调
,为什么要使用hack?
$firstHasBeenFound
变量在函数中不可用,因此这不起作用。您必须使用闭包(请参见Mark的答案)或使用
全局
(无论如何这不是一个好的做法)来实现此功能。错误。。。如果存在
preg\u replace\u回调
,为什么要使用hack?
$firstHasBeenFound
变量在函数中不可用,因此这不起作用。您必须使用闭包(参见Mark的答案)或使用
global
(这无论如何都不是一个好的实践)来实现这一点。我喜欢这个想法,但当您使用更大的正则表达式时,这将导致混乱。如果不是小规模的替换,这将是great@Martijn是的,可能会。因为这将需要持有1美元的团体,并将在最坏的情况下沉重!我喜欢这个想法,但是当你使用更大的正则表达式时,这会导致混乱。如果不是小规模的替换,这将是great@Martijn是的,可能会。因为这将需要持有1美元的团体,并将在最坏的情况下沉重!
$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);