用于preg_replace的网址正则表达式,但与 bbcode [url] 中的网址不匹配


Url regex for preg_replace but without matching the urls within the bbcode [url]

im 在网站上发表评论。起初,我需要做一个正则表达式来查找任何 url 并将其替换为

<a href="url"></a>  

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

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] 标签的 url 出现!其次,我替换了所有 bbcode 标签"

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

/(?i)''b((?![网址])(?:https?://|www''d{0,3}[.]|[a-z0-9.-]+[.][a-z]{2,4}/)(?:[^''s()<>]+|(([^''s()<>]+|(([^''s()<>]+)))))+(?:(([^''s()<>]+|(([^''s()<>]+))))|[^''s'!()[]{};:''''".,<>?«»'"'"'']))/

但没有用!

有点像正则表达式的新手,我尝试过的所有在线测试人员都不能很好地处理这么长的正则表达式。我不知道还有什么尝试。

你有什么建议吗?你知道任何PHP语言在有和没有[url] bbcode标签的情况下进行"url替换"吗?

提前谢谢你。

你在这里解决了两个问题。因此,单独解决它们,不要将所有内容都淬火到一个正则表达式中,这或多或少会使事情变得更加复杂而不是更少。

分而治之:

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

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

然后,您应用 bbcode 库仅在"bbcode"段上创建 URL,并且您的 URL 可点击制作工具将仅应用于"普通文本"段。

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

瞧,问题解决了。

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