代码之家  ›  专栏  ›  技术社区  ›  anno

使用preg_replace时,如何增加替换字符串中的计数?

  •  10
  • anno  · 技术社区  · 16 年前

    我有以下代码:

    $count = 0;    
    preg_replace('/test/', 'test'. $count, $content,-1,$count);
    

    对于每次替换,我都获得test0。

    我想得到test0、test1、test2等等。。

    6 回复  |  直到 16 年前
        1
  •  17
  •   cletus    16 年前

    使用 preg_replace_callback() :

    $count = 0;
    preg_replace_callback('/test/', 'rep_count', $content);
    
    function rep_count($matches) {
      global $count;
      return 'test' . $count++;
    }
    
        2
  •  7
  •   Emil Ivanov    16 年前

    使用 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'
    

    注:使用 global 这是一个艰难而快速的解决方案,但它会带来一些问题,所以我不推荐它。

        3
  •  4
  •   Gruffy    12 年前

    在PHP5.3发布之后,我们现在可以使用闭包和 use 关键字以绕过 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 在职能范围内(包括;使其通过引用传递,因此可从函数范围写入)。

        4
  •  3
  •   Jan Prichystal    10 年前

    此外,如果要避免使用全局变量,请执行以下操作:

    $count = 0; preg_replace_callback('/test/', function rep_count($matches) use (&$count) { return 'test' . $count++; }, $content);

        5
  •  3
  •   Casimir et Hippolyte    9 年前

    您只需在回调函数中定义一个静态变量:

    $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;
    
        6
  •  2
  •   Ignacio Vazquez-Abrams    16 年前

    preg_replace_callback() 将允许您在返回火柴进行后续更换之前对火柴进行操作。