PHP - preg_replace элементы в скобках с элементами массива - PullRequest
4 голосов
/ 16 декабря 2010

У меня есть массив:

array('id' => 'really')

У меня есть строка:

$string = 'This should be {id} simple.';

Я хочу закончить с:

This should be really simple.

У меня естьрегулярное выражение, которое будет работать с аспектом {id}, но мне трудно делать то, что я хочу.

/{([a-zA-Z\_\-]*?)}/i

{id} может быть чем угодно, {foo} или {bar} или чем-то, чтосоответствует моему регулярному выражению.

Я уверен, что в данный момент от меня ускользает простое решение.

Спасибо,

Джастин

Ответы [ 3 ]

5 голосов
/ 16 декабря 2010

str_replace быстрее, чем preg_replace, попробуйте это:

$arr = array('a' => 'a', 'b' => 'b');
$str = "{a} {b} {c}";
$values = array_values($arr);
$keys = array_keys($arr);

foreach ($keys as $k => $v) {
    $keys[$k] = '{'.$v.'}';
}

str_replace($keys, $values, $str);
4 голосов
/ 16 декабря 2010

Вы можете использовать preg_replace с модификатором e как:

$string = preg_replace('/{([a-zA-Z\_\-]*?)}/ie','$arr["$1"]',$string);

Ideone Link

Использование e модификатор, вы можете иметь любое PHP выражение в замещающей части preg_replace.

Теперь, почему ваше регулярное выражение /{([a-zA-Z\_\-])*?}/i не работает?

Вы положили*? за скобками захвата ( ) в результате вы захватываете только первый символ слова, найденного в { }.

Также обратите внимание, что вы не избежали { и }, которыеявляются метасимволом регулярного выражения, используемым для определения квантификатора диапазона {num}, {min,max}.Но в вашем случае не нужно , чтобы избежать их, потому что механизм регулярных выражений может сделать вывод из контекста, что { и } не могут использоваться в качестве оператора диапазона, поскольку они не имеют чисел в требуемом форматеих и, следовательно, относится к ним буквально.

1 голос
/ 16 декабря 2010

preg_replace_callback имеет опцию обратного вызова, которая делает подобные вещи возможными.

function replaceText($matches){
  global $data;
  return $data[$matches[1]];
}
preg_replace_callback(
        '/{([a-zA-Z\_\-])*?}/i',
        'replaceText',
        $content
);

Если вы не хотите использовать глобальную переменную, создайте класс и используйтеarray($object, 'method') нотация обратного вызова.

...