SoLoGHoST
SoLoGHoST

Reputation: 2689

Replace curly braced placeholders where the placeholder name starts with a dollar sign

Ok, I have this regex here:

$text = preg_replace('/\{\$(\w+)\}/e', '$params["$1"]', $text);

$params is an array where the key is scripturl and the value is what to replace it with.

So an example text would be {$scripturl} and passing through to this would give me ' . $scripturl . ' when I pass to $params an array that looks like so:

array('scripturl' => '\' . $scripturl . \'');

But I also need it to support brackets within the curly braces {}.

So I need this: {$context[forum_name]} to be caught with this regex as well.

So something like this should work:

array('context[forum_name]' => '\' . $context[\'forum_name\'] . \'');

So it would need to return ' . $context['forum_name'] . '

How can I make this possible within the preg_replace() that I am using?

If I need to create a separate regex just for this that is fine also.

Upvotes: 3

Views: 94

Answers (3)

mickmackusa
mickmackusa

Reputation: 47903

There were a few syntactic worries to resolve. I've generated some valid sample input and demonstrated how to match the placholders, then either replace them with existing values from the lookup array or leave the placeholder unaffected if it doesn't have a corresponding value in the lookup array.

None of the curly braces in the pattern are confused for having special meaning (as part of a quantifier expression), so they do not need to be escaped (but if you like excessive escaping, it won't damage the pattern).

Code: (Demo)

$context['forum_name'] = 'myForumName';

$params = [
    'context[forum_name]' => '\\' . $context['forum_name'] . '\\'
];

$text = 'Foo {$context[forum_name]} bar {$bar} blah';

echo preg_replace_callback(
         '/{\$([^}]+)}/',
         fn($m) => $params[$m[1]] ?? $m[0],
         $text
     );

Output:

Foo \myForumName\ bar {$bar} blah

The only fringe consideration with this task is how to handle {{double_brace_wrapped}} placeholders. With the above, the 2nd closing curly brace will not be consumed. It is easy to adjust the pattern to consume it, but then again it may be an occurrence that never manifests.

Upvotes: 1

RageZ
RageZ

Reputation: 27313

something like this should be able to it. it will catch everything between brackets

EDIT:

function replaceTemplateVariable($match){
  global $$match[1];
  return $$match[1];
}
preg_replace_callback('/\{[^\}]+\}/', 'replaceTemplateVariable', $text);

Also preg_replace_callback could help to make your code simpler

Upvotes: 1

Orbling
Orbling

Reputation: 20602

You may need to use preg_replace_callback() for that, but if you can get it working with the /e eval-modifier, then great.

Try changing the regexp to the following:

$text = preg_replace('/\{\$([\w\"\[\]]+)\}/e', '$params["$1"]', $text);

Upvotes: 1

Related Questions