Как заменить множество совпадений в одной строке на разные значения?..

Тема в разделе "PHP", создана пользователем bugargen, 14 сен 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. bugargen

    bugargen

    Регистр.:
    24 апр 2008
    Сообщения:
    232
    Симпатии:
    19
    Есть текст вида:
    PHP:
    Сунул {KEYруку в {KEY}
    Есть функция ran(), которая возвращает случайное значение.

    Нужно, чтобы КАЖДЫЙ раз, когда будет найдено вхождение {KEY}, вызывалась функция ran() с заменой {KEY} на возвращаемое ею значение!

    Это просто сделать, если в каждой строке всего по одному {KEY}, а вот если их несколько - моск сломал уже :be:
     
  2. m0nsieur

    m0nsieur Создатель

    Регистр.:
    30 июн 2008
    Сообщения:
    11
    Симпатии:
    4
    примерно так

    PHP:
    <?php
      $text 
    'Сунул {KEY} руку в {KEY}';
      function 
    _rand($input) {
        
    // здесь делаешь какую-нибудь рандомную выборку из своего массива, выражениями из которого собрался заменять возвращаешь это в конце ф-ии.
        
    return ;
      }
      
    $text preg_replace_callback('/{KEY}/''_rand'$text);
      echo 
    $text;
    ?>
    Еще примеры
    __http://ru.php.net/manual/en/function.preg-replace-callback.php
     
    bugargen нравится это.
  3. Holy Diver

    Holy Diver Создатель

    Регистр.:
    17 авг 2009
    Сообщения:
    22
    Симпатии:
    8
    Вот альтернативный способ, в теории работающий чуть быстрее.
    PHP:
    while(strpos($str'{KEY}') !== FALSE) {
        
    $str preg_replace('#{KEY}#'ran(), $str1);
    }
     
  4. antn

    antn Постоялец

    Регистр.:
    11 июл 2009
    Сообщения:
    104
    Симпатии:
    30
    А на практике работающий логически по другому и имеющий теоретический потенциал впадения в бесконечный цикл ))
    Да и каким образом компиляция одной регулярки и единичный проход по строке будет работать медленнее многократного повторения тех же действий? :)
     
  5. tostrss

    tostrss

    Регистр.:
    16 окт 2007
    Сообщения:
    771
    Симпатии:
    217
    PHP:
    $str preg_replace('%{KEY}%ie'"ran()"$str);
     
  6. bugargen

    bugargen

    Регистр.:
    24 апр 2008
    Сообщения:
    232
    Симпатии:
    19
    mOnsieur
    Хотел, сразу-слёту, было возразить, ибо пробовал я уже решить свою задачу с помощью callback, но потом, оценив эту функцию ещё разок - я, наконец, нашёл нужный мне путь.
    Возразить хотел, т.к. мне необходимо в свою функцию ran() передавать некое строковое значение, в зависимости от найденного вхождения, а в callback никаких дополнительных значений не впихнёшь, только название самой функции. В общем, решил я присвоение нужной строки делать в самой функции ran(). В итоге - всё просто замечательно работает! :ay:
    Большое спасибо!

    antn
    Тебя, я так понимаю, тоже нужно поблагодарить, ибо ваши мысли были схожи :)

    Holy Diver
    Твой пример, это первое, что приходит в голову. Так я, изначально, и кодил. Но, сцуко, preg_replace сначала находит все совпадения в строке, а потом уже заменяет их всех ОДНИМ и ТЕМ ЖЕ значением! Плюс к этому, функция, которая указана в качестве замены - вызывается сама собой! Т.е., как только доходит до строки вида preg_replace('/{KEY}/', ran(), $str), в независимости от того: обнаружено вхождение или нет, функция ran() всё-равно вызывается! Меня это хорошенько побесило :D Кстати, об этом я создам сейчас отдельную тему, ибо очень актуально..

    tostrss
    Модификатор e я уже пробовал использовать... В итоге - сплошные эрорры парсинга и фатал ерроры. Я х.з., как вообще с этим модификатором обращаться. Но ты уже второй мне это советуешь..
     
  7. antn

    antn Постоялец

    Регистр.:
    11 июл 2009
    Сообщения:
    104
    Симпатии:
    30
    Про передачу дополнительных параметров в callback => тема
     
  8. bugargen

    bugargen

    Регистр.:
    24 апр 2008
    Сообщения:
    232
    Симпатии:
    19
    Да, я её уже прочёл. Мой вариант, как раз соответствует твоему примеру "ПРОСТОЙ", только глобальные переменные мне не нужны и так всё гуд :)
     
  9. Holy Diver

    Holy Diver Создатель

    Регистр.:
    17 авг 2009
    Сообщения:
    22
    Симпатии:
    8
    antn
    В данном случае никаких зацикливаний нет и быть не может. Быстрее работает в том случае, если таких макросов несколько десятков или сотен, и большей части из них в тексте не присутствует - то есть мой вариант не выполняет регулярку в случае отсутствия в строке конструкции вида {KEY} и им подобных. Нет универсального решения, под каждую задачу оно своё. Сравнения производительности обычного варианта и callback я ещё не встречал, так что это остаётся вопросом.

    bugargen
    А я бы сначала почитал документацию на функцию:
    Мой пример какраз-таки не страдает заменой всех ОДНИМ и ТЕМ ЖЕ значением.
     
  10. antn

    antn Постоялец

    Регистр.:
    11 июл 2009
    Сообщения:
    104
    Симпатии:
    30
    Если ф-я ran вернёт строку содержащую {KEY} (условием это не запрещается), то эта подстрока будет заменена следующим проходом цикла. Если {KEY} будет присутствовать в возращаемом значении всегда, цикл не остановится.
    Насчёт скорости дискутировать не буду - в php это экономия на спичках :)
     
Статус темы:
Закрыта.