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.