如何防止第二个正则表达式重新替换?

时间:2015-12-21 23:48:29

标签: php html regex hyperlink

我在输入的路上有两个正则表达式:

// replace a URL with a link which is like this pattern: [LinkName](LinkAddress)
$str= preg_replace("/\[([^][]*)]\(([^()]*)\)/", "<a href='$2' target='_blank'>$1</a>", $str);

// replace a regular URL with a link
$str = preg_replace("/(\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|])/i","<a href=\"$1\" target=\"_blank\">untitled</a>", $str);

现在出现问题(某种程度上是碰撞)。对于常规URL,一切都很好。但是对于基于模式的URL,存在一个问题:第一个正则表达式创建了一个链接,第二个正则表达式再次创建其href - 属性值的链接。

我该如何解决?

编辑:根据评论,如何创建单个正则表达式而不是那两个正则表达式? (使用preg_replace_callback。老实说,我尝试了它,但它不适用于任何类型的URL ..

将它们组合成为可能吗?因为那些的输出并不相同。第一个具有LinkName,第二个具有常量字符串untitled作为其LinkName。

1 个答案:

答案 0 :(得分:3)

$str = preg_replace_callback('/\[([^][]*)]\(([^()]*)\)|(\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|])/i', 
function($matches) {
    if(isset($matches[3])) {
        // replace a regular URL with a link
        return "<a href='".$matches[3]."' target='_blank'>untitled</a>";
    } else {
        // replace a URL with a link which is like this pattern: [LinkName](LinkAddress)
        return "<a href=".$matches[2]." target='_blank'>".$matches[1]."</a>";
    }
}, $str);

echo $str;

一种方法就是这样做。您将两个表达式与替代字符|合并在一起。然后在你的回调函数中,你只需检查你的第三个捕获组是否已设置(isset($matches[3])),如果是,那么你的第二个正则表达式与字符串匹配,你替换正常的链接,否则你用link / linktext替换。 / p>

我希望你能理解一切,我可以帮助你。