为什么我的非贪婪Perl正则表达式什么都不匹配?

时间:2009-04-03 07:27:56

标签: regex perl greedy regex-greedy

我以为我在合理的范围内理解了Perl RE,但这令我感到困惑:

#!/usr/bin/perl
use strict;
use warnings;

my $test = "'some random string'";

if($test =~ /\'?(.*?)\'?/) {
       print "Captured $1\n";
       print "Matched $&";
}
else {
       print "What?!!";
}

打印

  

捕获
  匹配'

它似乎与'结局'相匹配,因此没有任何结果 我希望它能匹配整个事物,或者它完全不贪婪,什么都没有(因为一切都是可选的匹配)。
这种行为让我感到困惑,任何人都能解释发生了什么事吗?

5 个答案:

答案 0 :(得分:14)

开头和结尾的\'?表示贪婪地匹配0或1个撇号。 (正如另一张海报指出的那样,为了使它不贪婪,它必须是\'??

中间的.*?表示非贪婪地匹配0个或多个字符

Perl正则表达式引擎将查看字符串的第一部分。它将匹配开头,但是贪婪地这样做,所以它拿起了第一个撇号。然后它匹配非贪婪(所以尽可能少),然后是可选的撇号。这与空字符串匹配。

答案 1 :(得分:3)

我认为你的意思是:

/'(.*?)'/      // matches everything in single quotes

/'[^']*'/      // matches everything in single quotes, but faster

单引号不需要转义,AFAIK。

答案 2 :(得分:2)

pattern?贪婪,如果你想让它变得非贪婪,你必须说pattern??

#!/usr/bin/perl
use strict;
use warnings;

my $test = "'some random string'";

if($test =~ /\'?(.*?)\'?/) {
       print "Captured [$1]\n";
       print "Matched  [$&]\n";
}
if($test =~ /\'??(.*?)\'??/) {
       print "Captured [$1]\n";
       print "Matched  [$&]\n";
}
来自perldoc perlre的

  

以下标准量词得到承认:

*      Match 0 or more times
+      Match 1 or more times
?      Match 1 or 0 times
{n}    Match exactly n times
{n,}   Match at least n times
{n,m}  Match at least n but not more than m times
     

默认情况下,量化的子模式是“贪婪的”,也就是说,它会匹配   尽可能多的时间(给定一个特定的起始位置)   仍允许其余模式匹配。如果你想要它   匹配可能的最小次数,跟随量词   一个 ”?”。请注意,含义不会改变,只是“贪婪”:

*?     Match 0 or more times
+?     Match 1 or more times
??     Match 0 or 1 time
{n}?   Match exactly n times
{n,}?  Match at least n times
{n,m}? Match at least n but not more than m times

答案 3 :(得分:1)

注意使正则表达式的所有元素都是可选的(即所有元素都用*或?来量化)。这让Perl正则表达式引擎尽可能多地匹配(甚至没有),同时仍然认为匹配成功。

我怀疑你想要的是什么

/'(.*?)'/

答案 4 :(得分:1)

我想说的是你所寻找的最接近的答案是

/'?([^']*)'?/

所以“得到单引号,如果它在那里”,“得到任何东西和所有不是单引号”,“得到最后一个单引号,如果它在那里”。

除非你想匹配“'不要这样做'” - 但是谁在单引号中使用撇号(并且长时间侥幸逃脱)? :)