我有这段代码:
$count = 0;
preg_replace('/test/', 'test'. $count, $content,-1,$count);
对于每次替换,我都获得test0。
我想获得test0,test1,test2等。
答案 0 :(得分:15)
$count = 0;
preg_replace_callback('/test/', 'rep_count', $content);
function rep_count($matches) {
global $count;
return 'test' . $count++;
}
答案 1 :(得分:6)
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'
注意:使用global
是一种难以解决的解决方案,但它会引入一些问题,所以我不推荐它。
答案 2 :(得分:4)
在PHP5.3发布之后,我们现在可以使用闭包和use
关键字来解决Emil上面提出的global
问题:
$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>";
返回:
item1,
item2,
Found match 1: 23623!,
foo1,
foo2,
foo3,
Found match 2: 923653245!,
bar1,
bar2,
Found match 3: 43572342!,
bar3,
bar4
注意函数名后面的use (&$count)
- 这允许我们在函数范围内读取$count
(&amp;使其通过引用传递,因此可以从函数的范围写入)
答案 3 :(得分:3)
另外,如果您想避免使用global:
$count = 0;
preg_replace_callback('/test/', function rep_count($matches) use (&$count) {
return 'test' . $count++;
}, $content);
答案 4 :(得分:1)
preg_replace_callback()
将允许您在返回之前对匹配进行操作,以便后续替换。
答案 5 :(得分:1)
您只需在回调函数中定义一个静态变量:
$result = preg_replace_callback('/test/', function ($m) {
static $count = 0;
return 'test' . $count++;
}, $content);
这样就不会污染全局命名空间。
对于这种特殊情况,您还可以使用简单的功能:
$parts = explode('test', $content);
$end = array_pop($parts);
$result = '';
foreach($parts as $k=>$v) {
$result .= 'test' . $k;
}
$result .= $end;