我有一个使用preg_replace()
的函数,其中模式和替换是数组。我需要一个计数器来跟踪替换,所以我将函数转换为使用带有闭包的preg_replace_callback
,但我似乎无法找到一种方法来区分传递给回调的匹配匹配的模式。有没有办法做array =>使用preg_replace_callback进行数组替换?
理想情况下,这是我想要的工作,但显然它不会因为$ pattern和$ replace被评估进入调用而不是在每个替换之间
function replaceTags($text)
{
$i = 1;
$pattern = array(
'/\[d\](.*?)\[\/d\]/',
'/\[s\](.*?)\[\/s\]/',
);
$replace = array(
'<div id="'.($i++).'">$1</div>',
'<span id="'.($i++).'">$1</span>',
);
return preg_replace($pattern, $replace, $text);
}
答案 0 :(得分:0)
如果我理解正确,你只需要在调用回调函数之间保持状态。执行此操作的理想方法是使用成员函数。状态存储在对象实例中。每次调用时,都可以修改对象,改变状态。
我还为您的模式添加了额外的捕获,以便区分回调中的模式。
<?php
class TagReplacer {
private $counter = 0;
public function replacer($matches) {
// modify the state
$this->counter++;
// return the replacement text using the state
if ($matches[1] === "d")
$tag = 'div';
else
$tag = 'span';
return "<{$tag} id=\"{$this->counter}\">{$matches[2]}</{$tag}>";
}
}
function replaceTags($text) {
$stateObject = new TagReplacer();
$patterns = array(
'/\[(d)\](.*?)\[\/d\]/',
'/\[(s)\](.*?)\[\/s\]/',
);
return preg_replace_callback(
$patterns,
array(&$stateObject, "replacer"),
$text);
}
echo replaceTags("zzz[d]123[/d]zzz[s]456[/s]zzz[d]78[/d]zzz[s]90[/s]zzz");
?>
输出
zzz<div id="1">123</div>zzz<span id="3">456</span>zzz<div id="2">78</div>zzz<span id="4">90</span>zzz
我很惊讶ids不是按数字顺序排列的。我的猜测是preg_replace_callback遍历模式数组,为每个模式立即执行所有替换。