我正在阅读有关如何从网页中解析URL的问题,并且对提供此解决方案的可接受答案有疑问:
1
| ((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+) |
该解决方案由csmba提供,他将其归功于regexlib.com。呼。 学分完成。
我认为这是一个相当幼稚的正则表达式,但这是构建更好的东西的一个很好的起点。 但是,我的问题是这样的:
{1}的意义是什么? 它的意思是"恰好是先前的分组之一",对吗? 这不是正则表达式中分组的默认行为吗? 如果{1}被删除,表达式会以任何方式更改吗?
如果我从同事那里看到此错误,我会指出他或她的错误,但是在撰写本文时,响应的等级为6,而regexlib.com上的表达式的等级为5。因此,我可能遗漏了某些东西?
@Rob:我不同意。为了执行您要的请求,我认为您需要使用" negative-look-behind",这是可能的,但肯定与使用{1}不相关。 regexp的两个版本均未解决该特定问题。
让代码说话:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| tibook 0 /home/jj33/swap > cat text
Text this is http://example.com text this is
Text this is http://http://example.com text this is
tibook 0 /home/jj33/swap > cat p
#!/usr/bin/perl
my $re1 = '((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)';
my $re2 = '((mailto\:|(news|(ht|f)tp(s?))\://)\S+)';
while (<>) {
print"Evaluating: $_";
print"re1 saw \$1 = $1
" if (/$re1/);
print"re2 saw \$1 = $1
" if (/$re2/);
}
tibook 0 /home/jj33/swap > cat text | perl p
Evaluating: Text this is http://example.com text this is
re1 saw $1 = http://example.com
re2 saw $1 = http://example.com
Evaluating: Text this is http://http://example.com text this is
re1 saw $1 = http://http://example.com
re2 saw $1 = http://http://example.com
tibook 0 /home/jj33/swap > |
因此,如果两个版本之间存在差异,那么似乎并不是您建议的版本。
我认为{1}在该正则表达式中没有任何有效功能。
(**mailto:|(news|(ht|f)tp(s?))://){1}**
您应该将其读为:"将内容正确地捕获到一次"。但是我们并不十分在乎捕获此内容以备后用,例如替换中的$ 1。所以这毫无意义。
@Jeff Atwood,您的解释有点过头了-{1}表示完全匹配一次,但对"捕获"没有影响-由于括号而导致捕获-大括号仅指定模式必须匹配的次数来源-如您所说,一次。
我同意@Marius的观点,即使他的回答有点简洁,也有可能变得轻率。正则表达式很困难,如果不习惯使用正则表达式,并且问题中的{1}并不太错误-在支持正则表达式的系统中,它的意思是"完全匹配"。从这个意义上说,它实际上并没有做任何事情。
不幸的是,与现在删除的帖子相反,它不会阻止正则表达式匹配http://http://example.org,因为末尾的 S +将匹配一个或多个非空白字符,包括http://http://example.org中的http://example.org(使用Python 2.5进行了验证,以防万一我的regexp阅读功能关闭)。因此,给出的正则表达式实际上并不是最好的。我不是URL专家,但是可能有必要限制第一个字符之后的":"和" //"外观(以确保足够的URL)。
我认为它没有任何目的。但是由于RegEx几乎不可能理解/分解,所以人们很少指出错误。这可能就是为什么没有人指出这一点的原因。