preg_replace 替换第 1 组

preg_replace replace group #1

假设以下字符串:

@twitter @handles @hello

使用下面的代码,我可以替换字符串并生成链接

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
);

但上面的代码替换了第 0 组,而不是第 1 组。

Stack Overflow 上的很多问题都展示了如何用第 1 组替换第 0 组,但不是相反。

我的代码不是很清楚所以让我来说明问题:

第 1 组看起来像这样:

@twitter
@handles
@hello

但是第 0 组看起来像这样:

@twitter
 @handles
 @hello

它匹配空格,我不想要那个。

您可以将 (?:^|[^>]) 更改为 负面回顾 不会消耗:(?<!>)

另一种选择是use \K to reset beginning of the reported match: (?:^|[^>])\K

FYI:据我所知,除了使用 preg-replace-callback(您可以 modify/return 捕获任何组)之外,\K 是从正则表达式端更改完整报告部分 [0] 的唯一选项。

如果您希望左侧的空白边界不匹配 #@twitter,您也可以省略捕获组并使用否定后向断言 (?<!\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
);