I have this code :
$count = 0;
preg_replace('/test/', 'test'. $count, $content,-1,$count);
For every replace, I obtain test0.
I would like to get test0, test1, test2 etc..
I have this code :
$count = 0;
preg_replace('/test/', 'test'. $count, $content,-1,$count);
For every replace, I obtain test0.
I would like to get test0, test1, test2 etc..
Use preg_replace_callback()
:
$count = 0;
preg_replace_callback('/test/', 'rep_count', $content);
function rep_count($matches) {
global $count;
return 'test' . $count++;
}
Use preg_replace_callback()
:
class TestReplace {
protected $_count = 0;
public function replace($pattern, $text) {
$this->_count = 0;
return preg_replace_callback($pattern, array($this, '_callback'), $text);
}
public function _callback($matches) {
return 'test' . $this->_count++;
}
}
$replacer = new TestReplace();
$replacer->replace('/test/', 'test test test'); // 'test0 test1 test2'
Note: Using global
is the hard-and-fast solution but it introduces some problems, so I don't recommend it.
Following the release of PHP5.3 we can now use a closure and the use
keyword to get around the global
issue raised by Emil above:
$text = "item1,\nitem2,\nFINDME:23623,\nfoo1,\nfoo2,\nfoo3,\nFINDME:923653245,\nbar1,\nbar2,\nFINDME:43572342,\nbar3,\nbar4";
$pattern = '/FINDME:(\d+)/';
$count = 1;
$text = preg_replace_callback( $pattern
, function($match) use (&$count) {
$str = "Found match $count: {$match[1]}!";
$count++;
return $str;
}
, $text
);
echo "<pre>$text</pre>";
Which returns:
item1,
item2,
Found match 1: 23623!,
foo1,
foo2,
foo3,
Found match 2: 923653245!,
bar1,
bar2,
Found match 3: 43572342!,
bar3,
bar4
Note the use (&$count)
following the function name - this allows us to read $count
in the scope of the function (the & making it passed by reference and therefore writeable from the scope of the function).
Also, if you want to avoid using global:
$count = 0;
preg_replace_callback('/test/', function rep_count($matches) use (&$count) {
return 'test' . $count++;
}, $content);
preg_replace_callback()
will allow you to operate upon the match before returning it for subsequent replacement.
You only have to define a static variable in the callback function:
$result = preg_replace_callback('/test/', function ($m) {
static $count = 0;
return 'test' . $count++;
}, $content);
This way you don't pollute the global namespace.
For this specific case you can also use simple functions:
$parts = explode('test', $content);
$end = array_pop($parts);
$result = '';
foreach($parts as $k=>$v) {
$result .= 'test' . $k;
}
$result .= $end;