This is a tricky question here is what I am trying to do:
$str="abc def abc";
I want to replace first
occurrence of abc
with 123
and second
occurrence of abc
with 456
Now with preg_match it is possible that I replace first occurrence of abc with 123 like this
preg_replace('/abc/', '123', $str, 1);
But how to replace the second occurrence with 456 and most importantly how to do it at once and generate the required string (i.e 123 def 456).
Note: Strings are generated from external source.
Thanks Ahmar
You were very close:
$str = preg_replace('/abc/', '123', $str, 1); // will replace first 'abc'
$str = preg_replace('/abc/', '456', $str); // will replace all others
The reason this will work, is because the 2nd regex's first occurence, is actually the 2nd item.
Pro: Very readable, very easy to understand and implement
Con: the string will be regexed twice (bad for large strings), options are limited
If this is not what you want, you can use 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: A lot more variants can be made, more control over code, only one parse of the string
Con: More difficult to read/implement
In this example I use $firstHasBeenFound
, but you could use a increment to do something each 2nd, or something when you find match 7, etc
How about this one?:
$str = preg_replace('/abc(.*?)abc/', '123${1}456', $str, 1);
$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);
You may use preg_replace_callback
with closure
as callback (works in 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);