简体   繁体   中英

PHP preg_replace with variable value using found expression as key

I have a string $src with two variable placeholders %%itemA%% and %%itemB%% . The idea is for the regular expression to match any term listed ITEMA|ITEMB|ITEMC , case insensitively, and replace the term with the value of the array item using the term as the array key.

$replacements = [
    'itemA' => 'replacedItemA',
    'itemB' => 'replacedItemB',
    'itemC' => 'replacedItemC'
];

$src = "A B C %%itemA%% D E F %%itemB%% G H I";

$src = preg_replace('/\%\%(ITEMA|ITEMB|ITEMC)%%/i', $replacements['\1'], $src);

echo $src;

In this example the expected result is for %%itemA%% to be replaced with $replacements['itemA'] 's value and %%itemB%% to be replaced with $replacements['itemB'] 's value

Expected output from the echo was

ABC replacedItemA DEF replacedItemB GHI

Actual output, oddly, simply replaced the found terms with nothing (note the double spaces where the variable was removed)

ABCDEFGHI

Why is the term's string not being used in the $replacements['key'] to use the value of the array variable?

Your approach is wrong. Since you are dealing with literal strings, you can avoid the regex and use a faster way:

$replacements = [
    '%%itemA%%' => 'replacedItemA',
    '%%itemB%%' => 'replacedItemB',
    '%%itemC%%' => 'replacedItemC'
];

$str = strtr($str, $replacements);

You just need to replace the preg_replace with preg_replace_callback like this:

$src = preg_replace_callback('/%%(ITEM[ABC])%%/i', function ($m) use ($replacements) {
 return isset($replacements[$m[1]]) ? $replacements[$m[1]] : $m[0];
}
, $src);

See IDEONE demo

The issue is that \\1 backreference can only be used inside the pattern to refer to the text captured with the first capturing group or inside a replacement pattern, but only as a literal part of it. The \\1 is not automatically evaluated to be used as an argument.

I also contracted the pattern a bit, but I guess it is just a sample.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM