我有一个正则表达式来匹配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 :(得分: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+'$)