Preg_replace с заменой массива

$string = ":abc and :def have apples.";
$replacements = array('Mary', 'Jane');

должен стать:

Mary and Jane have apples.

Сейчас я делаю так:

preg_match_all('/:(\w+)/', $string, $matches);

foreach($matches[0] as $index => $match)
   $string = str_replace($match, $replacements[$index], $string);

Могу ли я сделать это за один проход, используя что-то вроде preg_replace?

Ответы

Ответ 1

Вы можете использовать preg_replace_callback с обратным вызовом, который использует ваши замены один за другим:

$string = ":abc and :def have apples.";
$replacements = array('Mary', 'Jane');
echo preg_replace_callback('/:\w+/', function($matches) use (&$replacements) {
    return array_shift($replacements);
}, $string);

Вывод:

Mary and Jane have apples.

Ответ 2

$string = ":abc and :def have apples.";
$replacements = array('Mary', 'Jane');

echo preg_replace("/:\\w+/e", 'array_shift($replacements)', $string);

Вывод:

Mary and Jane have apples.

Ответ 4

Для замены множественного и полного массивов Ассоциативным ключом вы можете использовать его для соответствия вашему шаблону регулярного выражения:

   $words=array("_saudation_"=>"Hello", "_animal_"=>"cat", "_animal_sound_"=>"MEooow");
   $source=" _saudation_! My Animal is a _animal_ and it says _animal_sound_ ... _animal_sound_ ,  _no_match_";


  function translate_arrays($source,$words){
    return (preg_replace_callback("/\b_(\w*)_\b/u", function($match) use ($words) {    if(isset($words[$match[0]])){ return ($words[$match[0]]); }else{ return($match[0]); } },  $source));
  }


    echo translate_arrays($source,$words);
    //returns:  Hello! My Animal is a cat and it says MEooow ... MEooow ,  _no_match_

* Обратите внимание, что, хотя "_no_match_" не имеет перевода, он будет соответствовать во время регулярного выражения, но сохранить свой ключ. И клавиши могут повторяться много раз.