Intereting Posts
Переменная URL GET имеет необходимый символ хэша Вставка значений в многомерный массив php Как отправить форму на две разные страницы в зависимости от нажатой кнопки, без javascript Как сохранить вложения электронной почты на сервер в PHP? Codeigniter с использованием базы данных доступа ms Как экспортировать строку Base64 в файл на стороне сервера, не сохраняя его на веб-сервере, напрямую с помощью PHP? Вызов PHP из Python Пользовательские поля WordPress для пользовательских типов сообщений Запросите отношение ManyToMany и покажите хороший результат в Symfony с Doctrine PHP Regex Любой персонаж is_uploaded_file () Задает файл изображения, когда он .bmp, почему? Отображение цвета другой границы, если поле действительно Найти массив ключей в php и изменить его значение или содержимое? Проблема с настройкой SMTP с помощью PHPMailer на сервере GoDaddy как ping ip-адреса в php и давать результаты

Как увеличить счетчик в строке замены при использовании preg_replace?

У меня есть этот код:

$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;