2011-04-14 137 views
1

我试图修改URL匹配的正则表达式在http://daringfireball.net/2010/07/improved_regex_for_matching_urls不匹配任何已经是一个有效的URL标记的一部分或用作链接文本的URL。正则表达式匹配后面没有“或<

对于例如,在下面的字符串,我想匹配http://www.foo.com,但不能http://www.bar.comhttp://www.baz.com

www.foo.com <a href="http://www.bar.com">http://www.baz.com</a> 

我试图添加一个负向前查找,排除比赛,其次是“或<,但由于某些原因,它只是应用到.com中的“m”。所以,这个正则表达式仍然会返回http://www.bar.cohttp://www.baz.co作为匹配。

我看不到我做错了什么...有什么想法?

\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))(?!["<]) 

下面是一个简单的例子太多:

((((ht|f)tps?:\/\/)|(www.))[a-zA-Z0-9_\-.:#/~}?]+)(?!["<]) 
+1

我一直认为使用正则表达式测试工具可以帮助! http://www.gskinner.com/RegExr/ – Paul 2011-04-14 16:22:00

+0

谢谢。我一直在使用其中之一。我也会试试这个,看它是否提供任何其他提示。 – 2011-04-14 16:28:42

+0

你在用什么语言? – ridgerunner 2011-04-14 20:11:16

回答

1

是的,如果你只是想排除尾随字符,只是让你的表达式'独立',那么在该段中不会发生回溯,这实际上是微不足道的。

(?>\b ...)(?!["<])

一个Perl测试:

use strict; 
use warnings; 

my $str = 'www.foo.com <a href="http://www.bar.com">http://www.baz.com</a>http://www.some.com'; 

while ($str =~ m~ 
(?> 
    \b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])) 
) 
(?!["<]) 
~xg) 
{ 
    print "$1\n"; 
} 

输出:

www.foo.com
http://www.some.com

+0

宾果 - 工作!谢谢! – 2011-04-14 22:35:52

2

我研究过这个问题,去年和发展,你可能想看看一个解决方案 - 请参阅:URL Linkification (HTTP/FTP)这个链接是一个测试页面Javascript解决方案包含很多难以链接的URL示例。

我正则表达式的解决方案,对于PHP和JavaScript编写的 - 不是简单的(但也不是问题,因为它证明。)有关详细信息,我也会推荐阅读:

The Problem With URLs由杰夫·阿特伍德和
An Improved Liberal, Accurate Regex Pattern for Matching URLs由约翰·格鲁伯

的注释以下Jeff的博客文章是,如果你想这样做的权利一定要读...

还要注意的是约翰·格鲁伯的正则表达式有可以进入灾难性的BAC的境界组件ktracking(与一个匹配括号相匹配的部分)。

+0

谢谢。这是一个非常有用的url格式列表。我认为我的问题的症结在于更多地关注如何在URL后面跟着一个“或”字符来排除网址匹配,我认为将匹配分组并跟随一个负向预测会起作用,但它似乎只是排除比赛的最后一个字母(例如.com中的m)。 – 2011-04-14 18:34:38