У меня есть этот код:
$count = 0; preg_replace('/test/', 'test'. $count, $content,-1,$count);
Для каждой замены я получаю test0.
Я хотел бы получить test0, test1, test2 и т. Д.
Используйте preg_replace_callback()
:
$count = 0; preg_replace_callback('/test/', 'rep_count', $content); function rep_count($matches) { global $count; return 'test' . $count++; }
Используйте 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
– это сложное и быстрое решение, но оно создает некоторые проблемы, поэтому я не рекомендую его.
После выпуска PHP5.3 мы теперь можем использовать закрытие и ключевое слово use
чтобы обойти global
проблему, поднятую Emil выше:
$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
в объеме функции (& & передавая ее по ссылке и, следовательно, записывая из области действия функции).
Кроме того, если вы хотите избежать использования глобальных:
$count = 0; preg_replace_callback('/test/', function rep_count($matches) use (&$count) { return 'test' . $count++; }, $content);
preg_replace_callback()
позволит вам работать с совпадением, прежде чем возвращать его для последующей замены.
Вам нужно только определить статическую переменную в функции обратного вызова:
$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;