所以我正在构建一个小型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 ' */
(?<![links)
(
/* match all combinations of protocol and www. */
(bhttps?://www.|bhttps?://|(?<!//)bwww.)
/* match URL (no changes made here) */
([^s()<>]+(?:([wd]+)|([^[:punct:]s]|/)))
/* but don't match if followed by [/link] - THIS DOESN'T WORK */
(?![/link])
)
www.
之前的否定表情是存在的,因为/
不是一个单词字符,没有它就有点像
[link http://www.example.com]example[/link]
将在CCD_ 3之后仍然匹配。
上面的regex生成以下匹配项(使用http://gskinner.com/RegExr/,匹配项位于粗体中。我不得不在http://
后面添加空格,因为我不允许发布更多的URL):
www.example.com
http://www.example.com
http://example.com
[链接http://www.example.com]没有问题1[/link]
[link www.example.com]没问题2[/link]
[链接http://www.example.com]http://www.example.com[/link]
我试着把消极的观点向前看,并玩括号(相当漫无目的),但没有成功。
为了完整起见,下面是标签匹配正则表达式(似乎有效):
(?:[links)(bhttps?://|bwww.|bhttps?://www.)([^s()<>]+(?:([wd]+)|([^[:punct:]s]|/)))](.*)(?:[/link])
我相信有人能立即发现错误。
提前感谢!
我已经获取了您的regex,用您给出的示例将其插入到regexr中,并试图使其工作。
逐步:
1) 原始正则表达式:http://regexr.com?33snj.为什么这个正则表达式也匹配[/link]的问题在于URL匹配位:
[^s()<>]+
这也将匹配开括号字符"[",因此匹配在遇到[/link]位时不会停止。可以说[字符是一个有效的URI字符,但这只是在极少数情况下(更多信息请参阅这篇stackoverflow文章)
2) 我决定继续使用正则表达式,但在否定字符列表中添加了开括号字符:
[^s()<>[]+
这会让你陷入另一个问题。看见http://regexr.com?33snp.由于回溯,引擎现在找到了一种方法来绕过最后的负面展望。
3) 一旦您使URL匹配组成为原子组(通过将?>添加到捕获组的开头),引擎就会停止回溯,我们就得到了所需的结果。
(?<![links)((bhttps?://www.|bhttps?://|(?<!//)bwww.)(?>[^s()<>[]+(?:([wd]+)|([^[:punct:]s]|/)))(?![/link]))
在行动中看到它http://regexr.com?33sns.