Intereting Posts
Установка pdo_mysql на Amazon EC2 с PHP 5.5 RHEL + PHP: запись файлов вне / var / www / html? Что такое жалоба RFC и регулярное выражение для проверки правильности строки? Более эффективный способ для COUNT () строк MYSQL через PHP? Как получить последний вставленный идентификатор? Проблемы с переносом сайта WordPress из локального сайта в галерею NextGen Отсутствует информация HTTP-Referrer о IE / FF (хорошо работает в Chrome / Safari) Я получаю предупреждение php: не могу изменить информацию заголовка (но у меня есть файл include перед html-кодом!) Сделать сценарий неудачным путем сериализации Closure Проверьте, установлены ли два объекта datetime PHP на одну дату (игнорируя время) Почему отображается это предупреждение: «Получена проблема 2 в узком парсере»? Как преобразовать массив байтов в целое число в php? Как не индексировать URL-адреса? Любой способ сохранить куки-файлы в памяти, а не на диске Внедрение системы голосования без регистрации

Замена токенов в строке из массива

Допустим, у меня есть строка

Этот $ 0 составляет $ 2 $ 1. Тем не менее, \ $$ 3 много заплатить за щенка.

и множество замен

array('puppy', 'cute', 'ridiculously', '1300') 

Каким будет самый чистый способ заменить токены в строке соответствующими элементами массива, разрешив мне обратную косую черту – избежать символа маркера (в данном случае $ )? Я также хочу заменить unmatched токены пустой строкой.

я думаю, вы имели в виду «\ $ 3», а не «\ $$ 3»,

 preg_replace('~(?<!\\\\)\$(\d+)~e', 'isset($array[$1])?$array[$1]:""', $source); 

Кстати, знаете ли вы, что sprintf также позволяет пронумеровать параметры ( http://php.net/manual/en/function.sprintf.php пример 3)

 foreach ($array AS $key => $value) { $string = str_replace('$' . $key, $value, $string); } 
 $test_sub= 'This $0 is $2 $1. Still, \$$3 is a lot to pay for a puppy.'; $GLOBALS['replacers'] = array('puppy', 'cute', 'ridiculously', '1300'); echo preg_replace_callback('/[^\$]\$([0-9])+/', create_function( '$matches', 'return $matches[0][0] . $GLOBALS[\'replacers\'][$matches[1]];' ), $test_sub ); 

Это POC, как это можно сделать. Простое регулярное выражение и обратный вызов для замены. Фактическая реализация зависит от того, что именно вы хотите с ней сделать. Надеюсь, это помогло.

Вот одна версия.

 $replacements = array('puppy', 'cute', 'ridiculously', '1300'); $input = 'This $0 is $2 $1. Still, \$3 is a lot to pay for a puppy.'; $output = preg_replace_callback('/(?<!\\\\)\$(\d+)/', 'replace_input', $input); echo $input . "<br>"; echo $output; function replace_input($matches) { global $replacements; $index = $matches[1]; return $index < 0 || $index >= count($replacements) ? $matches[0] : $replacements[$index]; } 

Вывод:

 This $0 is $2 $1. Still, \$3 is a lot to pay for a puppy. This puppy is ridiculously cute. Still, \$3 is a lot to pay for a puppy. 

Он обрабатывает обратную косую черту перед $, чтобы избежать этой переменной. Это может быть неудобным синтаксисом, потому что тогда вам нужно избегать обратных косых черт, что еще больше усложняет его (и в этом случае не обрабатывается). Регулярное выражение в основном означает $, за которым следует одна или несколько цифр, если $ не предшествует обратная косая черта (используя отрицательный lookbehind ).

Он использует глобальный массив для замены. Есть две альтернативы этому:

  1. Использовать закрытие (требуется PHP 5.3+); или
  2. Используйте create_function() .

Но я думаю, что глобальное проще и «глобально», если у вас нет веских оснований делать что-то другое, несмотря на обычное отвращение, которое мы испытываем к таким вещам.

Это решение следует за вопросом и немного заимствует ответ Джоша Лейцеля. Непревзойденные шаблоны (например, $ 4, $ 5) заменяются пустой строкой, удаляя их из ввода.

 $input = "This $0 is $2 $1. Still, \$$3 is a lot to pay for a puppy."; $replacements = array('puppy','cute','ridiculously','1300'); $pattern = "/[$]{1}([0-9]{1})/"; preg_match_all($pattern, $input, $matches); if (isset($matches[1])) foreach ($matches[1] as $key => $value) { $input = str_replace("$".$value, $replacements[$value], $input); } echo $input; 

Вывод:

Этот щенок смехотворно симпатичен. Тем не менее, $ 1300 – это много, чтобы заплатить за щенка.