Home > Net >  Replace every occurrence inside function with value
Replace every occurrence inside function with value

Time:02-10

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:

  1. 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);
  1. 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);
  1. 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 ...}}:

  • enter image description here

  • Related