使用 preg_replace 替换 href 值并防止重复问号

Use preg_replace to replace a href value and prevent duplicate question mark

我有这样的代码:

<?php
add_filter('the_content', 'my_url_replacer');
function my_url_replacer($content) {     
    $params = $_SERVER['QUERY_STRING'];
    if($params) {
        return preg_replace("/(?<=href=(\"|'))[^\"']+(?=(\"|'))/", "[=11=]?".$params, $content);
    } else {
        return $content;
    }
}
?>

它会将 $content 中的所有 href 标记值附加到 URL 中的查询字符串值。 例如:

如果页面 URL 是 https://example.com?param1=blue&param2=red - 并且 $content 包含 <a href="https://example.net">Awesome Button</a> - 它将被替换为 <a href="https://example.net?param1=blue&param2=red">Awesome Button</a>

基本上,查询字符串中的任何内容都将添加到内容中的 href 标记中。

当 href 已经有查询字符串时出现问题。例如,如果 href 值是这样的

<a href="https://example.net?tag=zero">Awesome Button</a> 

输出将是

<a href="https://example.net?tag=zero?param1=blue&param2=red">Awesome Button</a>

那里有两个问号。如果 a href 值已经有问号,如何防止出现重复问号问题?

您可以使用 preg_replace_callback:

preg_replace_callback("/(?<=href=[\"'])([^\"'?]+)(?:\?([^\"'?]+))?(?=[\"'])/", function($x) use ($params) {
   return !empty($x[2]) ? $x[1] . '?' . $params . '&' . $x[2] : $x[1] . '?' . $params;
}, $content);

看到一个PHP demo:

$content = '<a href="https://example.net">Awesome Button</a>
<a href="https://example.net?tag=zero">Awesome Button</a> ';
$params = 'param1=blue&param2=red';
echo preg_replace_callback("/(?<=href=[\"'])([^\"'?]+)(?:\?([^\"'?]+))?(?=[\"'])/", function($x) use ($params) {
   return !empty($x[2]) ? $x[1] . '?' . $params . '&' . $x[2] : $x[1] . '?' . $params;
}, $content);
# => <a href="https://example.net?param1=blue&param2=red">Awesome Button</a>
#    <a href="https://example.net?param1=blue&param2=red&tag=zero">Awesome Button</a> 

(?<=href=[\"'])([^\"'?]+)(?:\?([^\"'?]+))?(?=[\"']) 模式捕获字符串到 ? 的部分,第二部分是可选的(见最后的 ?)。如果第 2 组匹配,则 & 用于将 $params 连接到结果值,否则,仅将 ? + $params 添加到匹配中。