url正则表达式用于preg_replace但没有匹配bbcode中的url [url]

时间:2012-04-14 13:44:20

标签: php regex bbcode

我在网站上发表评论部分。 起初我需要做一个正则表达式,找到任何url并用

替换它
<a href="url"></a>  

所以我找到了一个超级正则表达式来查找注释中的所有url,我做了一个函数,返回所有带有html标记的url:

function addURLTags($string) {
    $pattern = "/(?i)\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/";
    return preg_replace($pattern, '<a href="$1">$1</a>', $string);
}

一切都很好。但一周前,我的老板告诉我,现在我必须在评论部分添加bbcode。我就像“没问题”......然后他告诉我,我的函数addURLTags必须留下来。

所以这样的字符串:

http://www.google.com
[url]http://www.google.com[/url]
[url="http://www.google.com"]http://www.google.com[/url]
必须将

替换为相同的字符串:

<a href="http://www.google.com">http://www.google.com</a>

所以我得到了一个小的php库,它将所有的bbcode代数替换为html代码。

我想:“好的,首先我应该在开始时获得所有没有[url]标签的网址!然后我将替换所有的bbcode标签”

我试图在超级正则表达式的开头添加否定断言,如下所示:

/ \ B(([网址])(:HTTPS:(Ⅰ')?!??| [。] // WWW \ d {0,3} | [A-z0-9.-] + [ (?:[^ \ S()] [AZ] {2,4} /)&LT;&GT;] + |(([^ \ S()&LT;&GT;] + |(([^ \ S( )&LT;&GT;] +)))))+(?:(([^ \ S()&LT;&GT;] + |(([^ \ S()&LT;&GT;] +)) ))| [!^ \ s`()[] {};:'“。?,&LT;&GT;«»‘\’ '']))/

但没有用!

我是一个有正则表达式的新手,我试过的所有在线测试人员都没有与这么长的正则表达式一起工作。我不知道还有什么尝试。

你有什么建议吗?你知道任何使用和没有[url] bbcode标签进行“url替换”的PHP lybrary吗?

提前谢谢。

2 个答案:

答案 0 :(得分:1)

你在这里解决了两个问题。所以单独解决它们并不要将所有东西都扼杀成一个正则表达式,这或多或少会使事情变得更复杂而不是更少。

分而治之:

首先使用您的bbcode库找到这些网址所在的部分,以便您可以创建文字流:

"normal text", "bbcode", "normal text", "bbcode"

然后您应用bbcode库仅在“bbcode”细分受众群中创建网址,而您的网址可点击制作者仅会应用于“普通文字”细分受众群。

处理完所有段后,将所有段连接回一个字符串。

Voila,问题解决了。

答案 1 :(得分:0)

最好首先解析[url] BBCode,然后将任何裸URL转换为链接。这可以通过使用负向lookbehind轻松实现,以确保URL之前没有双引号。这样做是因为您应该已经将原始字符串中的引号转换为&quot;,因此URL之前的任何实际引号都必须作为链接创建者的一部分放在那里。