正则表达式和分组

时间:2014-11-14 18:25:31

标签: regex perl

我有一个正则表达式来匹配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.

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

2 个答案:

答案 0 :(得分:2)

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

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

被解析为三种匹配的可能性

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

'\w+'$

要解决此问题,您有两个选择(我看到)。首先将每个选项扩展到您真正想要的选择:

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

第二种是对交替进行聚类:

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

答案 1 :(得分:1)

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

相当于

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

它匹配^后跟单词周围的空格或引号或单引号出现在字符串末尾的单词。

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

要求组内的所有人都从行的开头开始(由于组外的^),然后是各种测试,然后所有这些组必须在结束时完成字符串(由于组外的$)。

最简单的解决方法是将^$简单地移到群组中:

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