Home > other >  preg_replace replace group #1
preg_replace replace group #1

Time:11-07

Assume the following string:

@twitter @handles @hello

Using the code below, I can replace the strings and generate links

preg_replace(
    '/(?:^|[^>])(@' . $data->entities->user_mentions[$i]->screen_name . ')/',
    '<a href="https://twitter.com/' . $data->entities->user_mentions[$i]->screen_name . '">@' . $data->entities->user_mentions[$i]->screen_name . '</a>',
    $data->text
);

but the code above replaces group 0, not group 1

alot of questions on stackoverflow show people how to replace group 0 to group 1, but not the opposite. Thank you.

ok so my code isnt exactly clear so lemme illustrate problem:

group 1 looks like this:

@twitter
@handles
@hello

but group 0 looks like this:

@twitter
 @handles
 @hello

it matches the spaces and I don't want that.

CodePudding user response:

You could change (?:^|[^>]) to a negative lookbehind which won't consume: (?<!>)

Another option is to use \K to reset beginning of the reported match: (?:^|[^>])\K

FYI: Besides using preg-replace-callback (where you can modify/return captures of any group) as far as I know \K is the only option to alter the full reported part [0] from regex side.

CodePudding user response:

In case you want a whitespace boundary to the left to for example not match #@twitter, you can also omit the capture group and use a negative lookbehind assertion (?<!\S)

preg_replace(
    '/(?<!\S)@' . $data->entities->user_mentions[$i]->screen_name . '/',
    '<a href="https://twitter.com/' . $data->entities->user_mentions[$i]->screen_name . '">@' . $data->entities->user_mentions[$i]->screen_name . '</a>',
    $data->text
);
  • Related