I would like to replace every occurrence of @attribute2
with a value x
if the occurrence is within two curly braces. In the example below the two occurrences each in e2 and e3 should be replaced but not in e1.
How would I go about this?
<div >
<h1>e1 @attribute1,@attribute2,@attribute1,@attribute2</h1>
<h1>e2 {{ @attribute1,@attribute2,@attribute1,@attribute2 }}</h1>
<h1>e3 {{ addone(@attribute1,@attribute2,@attribute1,@attribute2) }}</h1>
<div>
CodePudding user response:
I see three possibilities:
- you assume that double closing curly brackets means that there are double opening brackets before. You check that you are between them with a lookahead that forbids all double opening curly brackets until the closing double curly brackets:
$pattern = '~@attribute2 (?= [^{}]* (?: {(?!{) [^{}]* | }(?!}) [^{}]* )* }} )~x';
$text = preg_replace($pattern, 'whatever', $text);
- This time you check that for opening brackets there are closing brackets. You look for a double curly bracket enclosed substring and use contiguity with
\G
to ensure you are always inside them:
$pattern = <<<'REGEX'
~
(?: (?!\A)\G | {{ (?= (?:(?! }} | {{ ).)* }} ) )
(?: (?! }} | @attribute2 ) . )* \K @attribute2
~xs
REGEX;
$text = preg_replace($pattern, 'whatever', $text);
- You search the whole bracketed part and you search inside it using
preg_replace_callback
in the callback function. (the most simple solution).
$text = preg_replace_callback(
'~{{.*?}}~s',
fn($m) => str_replace('@attribute2', 'whatever', $m[0]),
$text
);
CodePudding user response:
How about the following if you can use a variable-width lookbehind and lookahead to detect the opening and closing curly braces, {{...
and ...}}
: