2014-11-14 72 views
0

我有一个正则表达式来匹配x = y形式的字符串。即名称分配了一个值。该值可以选择性地引用和两个名称和值符合\ w +正则表达式和分组

我的正则表达式是

\w+=\w+|"\w+"|'\w+' 

可以有多个在同一行这些任务的,但在这里,我遇到了问题。由于某种原因,当我把这个正则表达式放在(?:)中时,它将不匹配。见测试用例下面

use Test::More; 

my $re1 = qr/^\w+=\w+|"\w+"|'\w+'$/p; 
my $re2 = qr/^(?:\w+=\w+|"\w+"|'\w+')$/p; 

ok('xy="abc"' =~ $re1); 

say "PREMATCH ${^PREMATCH}"; 
say "MATCH ${^MATCH}"; 
say "POSTMATCH ${^POSTMATCH}"; 


ok('xy="abc"' =~ $re2); 

done_testing; 

输出是

ok 1 
PREMATCH xy= 
MATCH "abc" 
POSTMATCH 
not ok 2 
# Failed test at ./test.pl line 20. 
1..2 
# Looks like you failed 1 test of 2. 

我不明白为什么第一场比赛和第二个不行。而且我也不明白为什么第一个匹配等号后的部分。

+0

你们是不是要同时匹配'xy'和'“ABC”'? – Degustaf 2014-11-14 19:08:26

回答

1

^\w+=\w+|"\w+"|'\w+'$ 

相当于

(?:^\w+=\w+)|(?:"\w+")|(?:'\w+'$) 

它的^其次是发生在的结束词或周围字的单引号周围的空格或引号匹配串。

^(?:\w+=\w+|"\w+"|'\w+')$ 

要求所有这些基团开始内的线(由于^以外的基团的)的开始,则各种测试,并的那么所有这些基团都必须在字符串的末尾完成(由于组外的$)。

最简单的解决方法是简单的两个^$进入到组:

(?:^\w+=\w+|"\w+"|'\w+'$) 
+0

是不是'^'只是变化的第一选择的一部分? – Degustaf 2014-11-14 19:00:58

+0

在$ re1的情况下,'^'是第一个替代选项的一部分。当在$ re2中遇到'(?:...)'组时,'^'被移到了我认为会导致一些问题的交替之外。 – OnlineCop 2014-11-14 19:03:56

2

您有您的轮换问题。它将第一个管道之前的整个正则表达式部分作为一个选项。换句话说,

/^\w+=\w+|"\w+"|'\w+'$/ 

被解析成三种可能性,以匹配

^\w+=\w+ 
"\w+" 

'\w+'$ 

为了解决这个问题,你有两个选择(我看到)。首先每个这些选择扩大到你真正想要的:

/^\w+=\w+|^\w+="\w+"|^\w+='\w+'$/ 

二是集群交替:

/^\w+=(?:\w+|"\w+"|'\w+')$/