区别?和*在正则表达式中 - 匹配相同的输入?

时间:2014-05-11 06:01:57

标签: regex perl

我无法理解正则表达式中?*之间的实际差异。我知道?表示检查前一个字符/组是否存在0或1次,而*表示检查前一个字符/组是否存在0次或更多次。

但是这段代码

while(<>) {
  chomp($_);
  if(/hello?/) {
    print "metch $_ \n";
  }
  else {
    print "naot metch $_ \n";
  }
}

hello?hello*提供相同的输出。提供给此Perl程序的外部文件包含

hello
helloooo
hell

输出

metch hello 
metch helloooo 
metch hell 

适用于hello?hello*。我无法理解?*

之间的确切区别

4 个答案:

答案 0 :(得分:10)

在Perl(和unlike Java)中,默认情况下m// - 匹配运算符未锚定

因此,所有输入都由/hello?//hello*/轻微匹配。也就是说,这些将匹配包含“地狱”的任何字符串(因为两个量词使“o”可选)在任何地方。

分别与/^hello?$//^hello*$/进行比较。由于这些使用锚点,前者将不匹配“helloo”(最多允许一个“o”),而后者将。


Regexp Quote-like Operators下:

  

m/PATTERN/ 搜索[字符串中的任何位置以进行模式匹配,并且在标量上下文中如果成功则返回true,如果失败则返回false。

答案 1 :(得分:5)

令您感到困惑的是,如果没有像^$这样的锚点,正则表达式模式匹配只会检查模式是否出现在目标字符串中的任何位置

如果您在 hello之后向模式添加内容,例如

if (/hello?, Ashwin/) { ... }

然后是字符串

hello, Ashwin

hell, Ashwin

会匹配,但

helloooo, Ashwin

不会,因为o和逗号hell之间的,字符过多。

但是,如果您改为使用明星*,例如

if (/hello*, Ashwin/) { ... }

然后所有三个字符串都匹配。

答案 2 :(得分:1)

?表示最后一项是可选的。 *表示它既是可选的,也可以包含多个项目。

  • 喂?匹配地狱,你好
  • hello *匹配hell,hello,helloo,hellooo,....

但是不使用^$意味着这些匹配可以出现在字符串中的任何位置

答案 3 :(得分:0)

这是我提出的一个例子,它非常清楚:

如果您只想匹配数十人,并且您的数据如下所示:

2 people. 20 people. 200 people. 2000 people.

在这种情况下,只有?会有用,而*会错误地捕获更大的数字。