I am trying to parse templates where tokens are delimited by @
on both sides.
Example input:
Hello, @name@! Please contact admin@example.com, dear @name@!
Desired output:
Hello, Peter! Please contact admin@example.com, dear Peter!
Naive attempt to find matches and replace:
$content = 'Hello, @name@! Please contact admin@example.com, dear @name@!';
preg_replace_callback(
'/(@.*@)/U', function ($token) {
if ('@name@' == $token) //replace recognized tokens with values
return 'Peter';
return $token; //ignore the rest
}, $content);
This regex doesn't correctly deal with spare @
- it matches first @name@
and @example.com, dear @
and fails to match the second @name
, because an @
is already spent before. The output is:
Hello, Peter! Please contact admin@example.com, dear @name@!
To prevent spending @
, I tried using lookarounds:
$content = 'Hello, @name@! Please contact admin@example.com, dear @name@!';
preg_replace_callback(
'/(?<=@)(.*)(?=@)/U', function ($token) {
if ('name' == $token) //replace recognized tokens with values
return 'Peter';
return $token; //ignore the rest
}, $content);
This correctly matches every substring that's included between a pair of @
s, but it doesn't allow me to replace the delimiters themselves. The output is:
Hello, @Peter@! Please contact admin@example.com, dear @Peter@!
How can I pass to callback anything between a pair of @
s and replace it replacing the @
s as well?
The tokens will not include newlines or @
.
Another example
This is a bit artificial, but to show what I would like to do as the current suggestions rely on word boundaries.
For input
Dog@Cat@Donkey@Zebra
I would like the calback to get Cat
to see if @Cat@
should be replaced with the token value and then receive Donkey
to see if @Donkey@
to be replaced.