Здравствуйте! Задача, найти все вхождения подстроки в строку и заменить их все, кроме первого! Например, дана строка: Нужно с помощью preg_replace заменить все вхождения bb на СС, например. Абсолютно все - не сложно, вот так: Код (Text): "/bb/i", "CC" . В итоге получается: Все, кроме первого, у меня не выходит. По идее нужно искать по такому принципу: если перед найденным bb через любое количество символов есть ещё один bb, значит найденный - не первый и его можно заменить. Реализую так: Код (Text): "/(bb.*)bb/i", "$1CC" В итогде получается Может это и типовая задачка, но нигде не нашёл решения и сам додуматься не могу как правильно и почему мой вариант не работает... Заранее благодарю за помощь.
PHP: <?php $what = 'bb'; $with = 'xx'; $string = 'aa-bb-cc aa-bb-cc aa-bb-cc aa-bb-cc'; $regexp = "/($what.*?)$what/"; while (preg_match($regexp, $string)) { $string = preg_replace($regexp, '$1'.$with, $string); } echo $string; // aa-bb-cc aa-xx-cc aa-xx-cc aa-xx-cc ?> Оно?
при том стоит заметить, что при одинаковом результате /($what.*)$what/ может быть в сотни раз медленнее, чем /($what.*?)$what/: PHP: <?php $s = microtime(1); $what = 'bb'; $with = 'xx'; $string = 'aa-bb-cc '; $string = str_repeat ($string, 5000); /*** * 0.0467569828033 * 0.0468139648438 * 0.0451989173889 */ $regexp = "/($what.*?)$what/"; /*** * 13.2560789585 * 13.9170439243 * 13.7839291096 */ $regexp = "/($what.*)$what/"; while (preg_match($regexp, $string)) { $string = preg_replace ($regexp, '$1'.$with, $string); } echo (microtime(1) - $s); ?>
Не, с жадностью вчера тоже разобрался. Всё-равно не работает, поэтому не стал писать. Причём я сейчас тренируюсь на bb, чтобы понять принцип, а потом у меня будут теги, все с разными параметрами (например, тег IMG с параметрами src). Поэтому через str_replace не получится обойтись. Если только не сделать preg_match_all, получить массив всех вариаций bb, первый не заменять, а остальные через str_replace? Но даже если так получится, всё-равно теперь интересно, какое должно быть регулярное выражение для preg_replace, чтобы работал вышеприведёный пример с bb?
TheShock сейчас испытаю его в деле Мне не понятно, зачем нужен цикл? Я думал preg_replace итак проходит всю строку.
делаю так: PHP: <?php $pregm[] = array("/(bb.*?)bb/i", '$1'."CC"); foreach($pregm as $preg) { echo "<DIV style='overflow: auto; width: 100%; max-height: 300px;'>"; while (preg_match($preg[0], $txt)) { $txt = preg_replace($preg[0], $preg[1], $txt); } echo $txt."<BR>"; echo "</DIV>"; } ?> Заменяет все варианты, даже первый.... из получаем
Заработало. Благодарю за помощь. Я ошибся сам, во-первых, поэтому все элементы заменялись. Во-вторых, нужно ставить модификаторы /is, потому что строка берётся из файла в несколько строчек. Радует, что изначально я подобрал примерно правильное регулярное выражение Жаль только не додумался до цикла...