Home > Software design >  Looking for assistance trying to understand a strange scenario where `preg_replace` won't work
Looking for assistance trying to understand a strange scenario where `preg_replace` won't work

Time:01-20

So I have these 3 strings:

$campaignId = 'br_B081D4LCMX_v2';
$adgroupId = '006_B081D4LCMX_{{adgroupQS}}';
$creativeId = '';

And the following string

$url = '?maas=maas_adg_api_587443019484609215_static_9_51&ref_=aa_maas&aa_campaignid={insertCampaign}&aa_adgroupid={insertAdGroupId}&aa_creativeid={insertCreativeId}';

I am trying to replace all what's inside {} by the correspondent variable.

I tried this:

$url = preg_replace([
  '/(aa_campaignid=)[^&] /',
  '/(aa_adgroupid=)[^&] /',
  '/(aa_creativeid=). /'
], [
  '$1' . $campaignId, // Tried with "$1{$campaignId}" too
  '$1' . $adgroupId,
  '$1' . $creativeId
], $url);

And I expected the following result:

?maas=maas_adg_api_587443019484609215_static_9_51&ref_=aa_maas&aa_campaignid=br_B081D4LCMX_v2&aa_adgroupid=006_B081D4LCMX_{{adgroupQS}}&aa_creativeid=

But I obtained this instead

?maas=maas_adg_api_587443019484609215_static_9_51&ref_=aa_maas&aa_campaignid=br_B081D4LCMX_v2&06_B081D4LCMX_{{adgroupQS}}&aa_creativeid=

For some reason aa_adgroupid is completely replaced instead of using the group $1 obtained from the regexp.

When I updated my code to use preg_replace_callback instead of preg_replace, it worked perfectly. Here is the code for reference

$replacements = [
  $campaignId,
  $adgroupId,
  $creativeId
];

$url = preg_replace_callback([
  '/(aa_campaignid=)[^&] /',
  '/(aa_adgroupid=)[^&] /',
  '/(aa_creativeid=). /'
], function ($matches) use (&$replacements) {
  return $matches[1] . array_shift($replacements);
}, $url);

Same regular expressions, same string, same "position" (assuming matches[1] should be the same as $1 in my previous example)

The solution to the problem with my first example may be in front of my eyes but I am not being able to find it despite I spent hours looking at it and trying different options.

Does anyone sees anything wrong with it? Any idea why it is not working as expected?

CodePudding user response:

You need to use

'${1}' . $adgroupId

or else your replacement ends up as

$1006_B081D4LCMX_{{adgroupQS}}

and capture group #10 does not exist.

Hence, why you end up with:

&06_B081D4LCMX_{{adgroupQS}}

and the leading zero is missing.

It's not enough to merely understand PHP variable interpolation, you have to remember that certain characters and syntaxes have special meaning in BOTH regex expressions and the replacement string.

You've avoided the issue via preg_replace_callback() because you're accessing $matches[1] and not $matches[10].

  • Related