2012-11-21 142 views
2

以下似乎匹配, 有人可以解释为什么吗?Perl正则表达式 - 为什么正则表达式/[0-9.]+(,,)/匹配逗号

我想匹配多个数字或点,以逗号结尾。

123.456.768, 
123, 
., 
1.2, 

但这样做以下意外打印,

my $text = "241.000,00"; 
foreach my $match ($text =~ /[0-9\.]+(\,)/g){ 
    print "$match \n"; 
} 
print $text; 

# prints 241.000, 
#  , 

更新:
逗号,因为匹配: In list context, //g returns a list of matched groupings, or if there are no groupings, a list of matches to the whole regex 作为here.定义

+0

您不需要转义逗号;如果你不打算捕捉它们,你不需要这些parens。你想打印/ caputre究竟是什么? – NullUserException

+0

不知道这里的问题是什么。你的捕获组包含一个转义的逗号(不确定反斜杠对Perl中的逗号有什么影响),所以我希望这会返回一个逗号作为捕获的字符串。 –

+0

请编辑你的问题来完成你的想法 - “我怎么能匹配更多的长度的数字比,哪个”...? – maerics

回答

4

使用zero-width positive look-ahead assertion排除从比赛本身的逗号:

$text =~ /[0-9\.]+(?=,)/g 
+0

目前尚不清楚,perl regexp只返回'()'所包含的matchpart。我用它们对正则表达式的部分进行分组。为此,存在非matchin括号:http://stackoverflow.com/questions/13502565/how-to-get-a-list-matches-without-groupings – Skip

4

您在foreach循环比赛是在列表上下文中。在列表上下文中,匹配返回其捕获的内容。 Parens表示捕获,而不是整个正则表达式。你的逗号周围有一个逗号。你想以相反的方式,把你想要的东西放在你的肩上。

my $text = "241.000,00"; 

# my($foo) puts the right hand side in list context. 
my($integer_part) = $text =~ /([0-9\.]+),/; 

print "$integer_part\n"; # 241.000 
3

如果你不想匹配逗号,使用前向断言:

/[0-9\.]+(?=,)/g 
1

你可以用逗号代替逗号,或者完全排除逗号,因为它不是你想捕捉的部分,它在这种情况下不会有什么不同。但是,该模式会将逗号而不是数字放入捕获组1,然后甚至不会通过捕获组引用,而是返回整个匹配。

这是一个捕获组是如何获得:

$mystring = "The start text always precedes the end of the end text."; 
if($mystring =~ m/start(.*)end/) { 
    print $1; 
} 
2

你捕捉错误的东西!将逗号从逗号周围移到数字附近。

$text =~ /([0-9\.]+),/g