此正则表达式中{1}的目的是为了匹配url协议

时间:2020-03-05 18:40:07  来源:igfitidea点击:

我正在阅读有关如何从网页中解析URL的问题,并且对提供此解决方案的可接受答案有疑问:

((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)

该解决方案由csmba提供,他将其归功于regexlib.com。 ew。学分完成。

我认为这是一个相当幼稚的正则表达式,但这是构建更好的东西的一个很好的起点。但是,我的问题是这样的:

" {1}"的意义是什么?它的意思是"恰好是先前的分组之一",对吗?这不是正则表达式中分组的默认行为吗?如果删除了{1},表达式会以任何方式改变吗?

如果我从同事那里看到此错误,我会指出他或者她的错误,但是在撰写本文时,响应的等级为6,而regexlib.com上的表达式的等级为5. 4. 那么,也许我遗漏了某些东西吗?

解决方案

回答

我认为它没有任何目的。但是由于RegEx几乎不可能理解/分解,所以人们很少指出错误。这可能就是为什么没有人指出这一点的原因。

回答

@Rob:我不同意。要执行我们要的请求,我认为我们需要使用" negative-look-behind",这是可能的,但肯定与使用{1}不相关。 regexp的两个版本均未解决该特定问题。

让代码说话:

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 = \n" if (/$re1/);
  print "re2 saw $1 = \n" if (/$re2/);
}
tibook 0 /home/jj33/swap > cat text | perl p
Evaluating: Text this is http://example.com text this is
re1 saw  = http://example.com
re2 saw  = http://example.com
Evaluating: Text this is http://http://example.com text this is
re1 saw  = http://http://example.com
re2 saw  = http://http://example.com
tibook 0 /home/jj33/swap >

因此,如果两个版本之间存在差异,则似乎不是我们建议的版本。

回答

@Jeff Atwood,解释有点偏离{1},意味着只匹配一次,但是对"捕获"没有影响,因为括号将括号括起来,仅指定了模式必须与源匹配一次的次数, 正如你所说。

我同意@Marius的观点,即使他的回答有点简洁,也有可能变得轻率。正则表达式很棘手,如果不习惯使用正则表达式,并且问题中的{1}在支持它的系统中不是很错误,那确实意味着"完全匹配"。从这个意义上说,它实际上并没有做任何事情。

不幸的是,与现在删除的帖子相反,它不会阻止regexp与http:// http:// example.org匹配,因为末尾的\ S +将匹配一个或者多个非空格字符,包括" http:// http://example.org"中的" http://example.org"(已使用Python 2.5进行了验证,以防我的正则表达式关闭)。因此,给出的正则表达式实际上并不是最好的。我不是URL专家,但是为了确保良好的URL,可能有必要限制第一个字符之后的":"和" //"的外观(但几乎不够)。

回答

我认为{1}在该正则表达式中没有任何有效功能。

(**mailto:|(news|(ht|f)tp(s?))://){1}**

我们应该将其读为:"将对象中的内容完全捕获一次"。但是,我们并不十分在乎捕获此内容以供以后使用,例如替换中的$ 1. 所以这是没有意义的。