2012-07-18 115 views
0

我有一个函数,它使用preg_replace()其中模式和替换是数组。我需要一个计数器来跟踪替换,所以我将函数转换为使用preg_replace_callback和闭包,但我似乎无法找到一种方法来区分传递到回调匹配的匹配模式。有没有办法使用preg_replace_callback做array =>数组替换?preg_replace_callback数组模式和替换

理想的情况下,这是想我的工作,但显然它不会因为$模式,$替代评估进入呼叫,并且其间没有每次更换

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

['preg_replace'](http://us2.php.net/manual/en/function.preg-replace.php)已经支持array - >数组替换。它不符合你的需求吗? – 2012-07-18 01:45:15

+0

我需要一个更换柜台用于更换本身,所以preg_replace不会工作 – flurry 2012-07-18 01:47:56

+0

您可以采取简单的方法,并单独计数和替换。 – 2012-07-18 01:49:55

回答

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 

我很惊讶的是,ID不按数字顺序排列。我的猜测是,preg_replace_callback遍历模式数组,对每个模式一次执行所有替换。

+0

是的,这是我想要做的,但我的模式和替换参数是数组。如果说明了这一点,我会在这个问题上增加一个例子。 – flurry 2012-07-18 04:59:14

+0

@Slipflurry这是你要找的更多吗? – walrii 2012-07-18 06:25:29