4

所以我正在构建一个小型 CMS,我想避免在内容编辑器中允许 HTML。出于这个原因,我想检测文本中的原始 URL 以及支持类似 BB 的标签,以便更好地定制。

www.example.com
[link http://www.example.com]Click me[/link]

不幸的是,我对正则表达式还很陌生,我似乎无法让它工作。我在字符串上运行了两个正则表达式:第一个检测原始 URL,第二个检测类似 BB 的 URL。后者似乎工作得很好,但第一个会干扰,并且也会转换包含在标签中的 URL。

我从在这里找到的一段代码开始,并做了一些补充。

这是非标记 URL 的代码:

/* don't match URLs preceeded by '[link ' */
(?<!\[link\s)
(
    /* match all combinations of protocol and www. */
    (\bhttps?://www\.|\bhttps?://|(?<!//)\bwww\.)

    /* match URL (no changes made here) */
    ([^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))

    /* but don't match if followed by [/link] - THIS DOESN'T WORK */
    (?!\[/link\])
)

之前的负面后视www.是因为/不是单词字符,没有它就像

 [link http://www.example.com]example[/link]

之后仍然会匹配http://

上面的正则表达式产生以下匹配(用http://gskinner.com/RegExr/测试,匹配以粗体显示。我必须在后面添加空格,http://因为我不允许发布更多 URL):

www.example.com
http:// www.example.com
http://example.com
[链接http://www.example.com]没问题 1[/link]
[链接 www.example.com]没问题2[/link]
[链接http://www.example.com] http://www.example.com[/link ]

我尝试移动负面的前瞻性并使用括号(非常漫无目的),但没有成功。

为了完整起见,这是标签匹配的正则表达式(似乎有效):

(?:\[link\s)(\bhttps?://|\bwww\.|\bhttps?://www\.)([^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))\](.*)(?:\[/link\])

我相信有人可以立即发现错误。

提前非常感谢!

4

1 回答 1

0

我已经采用了您的正则表达式,并使用您提供的示例将其插入到 regexr 中,并试图使其工作。

一步步:

1)原始正则表达式:http ://regexr.com?33snj 。这个正则表达式也匹配 [/link] 的问题在于 URL 匹配位:

[^\s()<>]+

这也将匹配左括号字符“[”,因此当遇到 [/link] 位时匹配不会停止。可以说 [ 字符是有效的 URI 字符,但这仅在极少数情况下(有关更多信息,请参阅stackoverflow 帖子)。

2)我决定继续使用您的正则表达式,但将左括号字符添加到否定字符列表中:

[^\s()<>[]+

这会让你陷入另一个问题。请参阅http://regexr.com?33snp。由于回溯,引擎现在在最后找到了一种绕过负前瞻的方法。

3) 一旦你使 URL 匹配组原子化(通过添加 ?> 到捕获组的开头),引擎停止回溯,我们已经达到了预期的结果。

(?<!\[link\s)((\bhttps?://www\.|\bhttps?://|(?<!//)\bwww\.)(?>[^\s()<>[]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))(?!\[/link\]))

在http://regexr.com?33sns中查看它。

于 2013-02-23T17:13:38.397 回答