php preg_replace 或表达式替换除第一个匹配项以外的所有内容

php preg_replace or expression replace all but first match

大家好,能帮我解开这个谜语吗?

我有一组非常大的关键字,用于匹配内容中的这些关键字。

示例:$array('game','gamers','gaming');等...

我正在使用此 foreach 方法循环遍历每个关键字并将其与内容匹配,但在某些情况下,内容可能非常大,超过 50 个关键字和每页超过 20 个帖子会显着降低网站速度。

foreach($array as $key => $vall)
{

$pattern = '/\b'.$vall.'\b/';

$data['content'] = preg_replace($pattern, " <a style=\"font-weight: bold;color:rgb(20, 23, 26);\" href=\"".$url."\">".$vall."</a>", $data['content'],1);    
}

好处是我可以将替换限制指定为一个,这意味着它不会替换该关键字的所有实例。

上述方法对性能没有影响。

我的另一种方法是这个,但有一个问题。我无法指定限制。

$pattern = '/\bgamers|gaming|gamer\b/';
$data['content'] = preg_replace($pattern, " <a style=\"font-weight: bold;color:rgb(20, 23, 26);\" href=\"".$url."\">[=13=]</a>", $data['content']);

上述方法效果很好,但它会替换匹配关键字的所有实例。

问题。如何添加到由 or 表达式分隔的模式关键字,然后仅替换每个关键字的第一个匹配项。

更新。

$string = 'I am a gamer and I love playing video games. Video games are awesome. I have being a gamer for a long time. I love to hang-out with other gamer buddies of mine.';

$keyWordsToMatch = 'gamer,games';

对于输出,它只需要替换 $keyWordsToMatch 的第一个实例。

像这样:

$string = 'I am a (gamer)_replace and I love playing video (games)_replace. Video games are awesome. I have being a gamer for a long time. I love to hang-out with other gamer buddies of mine.';

我认为您可以通过使用 preg_replace_callback 并跟踪您找到的关键字来解决这个问题。我还添加了 @Wiktor Stribiżew 建议的分组,我个人喜欢在 RegEx 中使用命名捕获。

查看评论了解更多详情

$string = 'gamer thing gamer games test games';
$pattern = '/\b(?<keyword>gamer|games)\b/';

// We'll append to this array after we use a given keyword
$usedKeywords = [];
$finalString = preg_replace_callback(
    $pattern,

    // Remember to capture the array by-ref
    static function (array $matches) use (&$usedKeywords) {
        $thisKeyword = $matches['keyword'];
        if (in_array($thisKeyword, $usedKeywords, true)) {
            return $thisKeyword;
        }

        $usedKeywords[] = $thisKeyword;
        
        // Do your replacement here
        return '~'.$thisKeyword.'~';

    },
    $string
);

print_r($finalString);

输出为:

~gamer~ thing gamer ~games~ test games

此处演示:https://3v4l.org/j40Oq