我有一个正则表达式,它与文本文件中一行内的多个字符串匹配。但是,当我使用它尝试打印捕获的组的所有实例时,它仅打印第一个实例。
我的正则表达式是:
/"resolution.(\w+)/g
将以下行输入到正则表达式时:
"signalcfg": "{\"signals\":[{\"order\":1,\"id\":\"oryx_C20C0E15-2028-4F4B-A8DD-0DA8D87B4FF9\",\"name\":\"success\",\"rrcodes\":\"resolution.COMPLAINTS_CHANGE_STATUS_SUCCESS\",\"testModule\":\"MCSChangeComplaintsStatus\",\"default\":false},{\"order\":2,\"id\":\"oryx_C943ADB8-6FA2-4DA1-B4D7-24515D96B9DA\",\"name\":\"TimeOut\",\"rrcodes\":\"resolution.MCS_CHANGE_COMPLAINTS_STATUS_TIMEOUT\",\"testModule\":\"MCSChangeComplaintsStatus\",\"default\":false},{\"order\":3,\"id\":\"oryx_0CAC0F97-AD57-4C49-807A-B41839191F74\",\"name\":\"Warning\",\"rrcodes\":\"resolution.MCS_CHANGE_COMPLAINTS_STATUS_WARNING\",\"testModule\":\"MCSChangeComplaintsStatus\",\"default\":false},{\"order\":4,\"id\":\"oryx_4583A3EC-DFC8-47B9-9B04-DEE71DC3F17A\",\"name\":\"APIError\",\"rrcodes\":\"resolution.COMPLAINTS_CHANGE_STATUS_FAIL,resolution.MCS_CHANGE_COMPLAINTS_STATUS_FAIL\",\"testModule\":\"MCSChangeComplaintsStatus\",\"default\":true}]}",
它匹配所有这样的表达式:
"resolution.COMPLAINTS_CHANGE_STATUS_SUCCESS
我已经尝试过打印实例捕获组:
perl -ne 'print "$1\n" if /"resolution.(\w+)/g' FILE_NAME
perl -ne 'print "$1\n" if m/"resolution.(\w+)/sig' FILE_NAME
我希望得到:
OPEN_IT_COMPLAINTS_FOUND
OPEN_IT_COMPLAINTS_NOT_FOUND
MCS_GET_COMPLAINTS_WARNING
MCS_GET_COMPLAINTS_TIMEOUT
MCS_GET_COMPLAINTS_FAIL
但是我只会得到:
OPEN_IT_COMPLAINTS_FOUND
如果我将上述类型的表达式分别放在文件内的一行中,如下所示:
\"rrcodes\":\"resolution.OPEN_IT_COMPLAINTS_NOT_FOUND1\"
\"rrcodes\":\"resolution.OPEN_IT_COMPLAINTS_NOT_FOUND2\"
\"rrcodes\":\"resolution.OPEN_IT_COMPLAINTS_NOT_FOUND2\"
\"rrcodes\":\"resolution.OPEN_IT_COMPLAINTS_NOT_FOUND4\"
我确实得到了预期的输出:
OPEN_IT_COMPLAINTS_NOT_FOUND1
OPEN_IT_COMPLAINTS_NOT_FOUND2
OPEN_IT_COMPLAINTS_NOT_FOUND2
OPEN_IT_COMPLAINTS_NOT_FOUND4
答案 0 :(得分:2)
if /.../g
在标量上下文中使用正则表达式。在这种情况下,/.../g
仅返回单个匹配项。下一个/.../g
将返回下一个匹配项,等等:
$ perl -ne '
print "$1\n" if /"resolution.(\w+)/g;
print "$1\n" if /"resolution.(\w+)/g;' file
COMPLAINTS_CHANGE_STATUS_SUCCESS
MCS_CHANGE_COMPLAINTS_STATUS_TIMEOUT
如果想要所有匹配项,则必须在标量上下文中重复调用/.../g
或在数组上下文中使用它。第一个选项如下所示:
$ perl -ne 'print "$1\n" while /"resolution.(\w+)/g' file
COMPLAINTS_CHANGE_STATUS_SUCCESS
MCS_CHANGE_COMPLAINTS_STATUS_TIMEOUT
MCS_CHANGE_COMPLAINTS_STATUS_WARNING
COMPLAINTS_CHANGE_STATUS_FAIL
在数组上下文/.../g
中以数组的形式一次返回所有匹配项,即
@matches = /"resolution.(\w+)/
在某些命令行语句中,可能看起来像这样:
$ perl -ne 'print map { "$_\n" } /"resolution.(\w+)/g'
COMPLAINTS_CHANGE_STATUS_SUCCESS
MCS_CHANGE_COMPLAINTS_STATUS_TIMEOUT
MCS_CHANGE_COMPLAINTS_STATUS_WARNING
COMPLAINTS_CHANGE_STATUS_FAIL
答案 1 :(得分:1)
标量vs.列表上下文:
$ perl -ne 'print "$_\n" foreach (/"resolution\.(\w+)/g)' dummy.txt
COMPLAINTS_CHANGE_STATUS_SUCCESS
MCS_CHANGE_COMPLAINTS_STATUS_TIMEOUT
MCS_CHANGE_COMPLAINTS_STATUS_WARNING
COMPLAINTS_CHANGE_STATUS_FAIL
即/g
仅在正则表达式被重复执行时才返回多个结果。您的命令行只执行一次匹配。
也许下面的代码示例使其更加清晰;
#!/usr/bin/perl
use strict;
use warnings;
my $re = qr/string\.(\w+)/;
my $input = "asdlkj string.TEST1 daklkl string.TEST2 kasöldk";
my($scalar) = ($input =~ /$re/g);
print "SCALAR: $scalar\n";
my @array = ($input =~ /$re/g);
print "ARRAY: @array\n";
exit 0;
答案 2 :(得分:1)
在您的输入文件中看不到OPEN_IT。
尝试遍历比赛:
perl -ne 'print "$_\n" for (/"resolution.(\w+)/g)' FILE_NAME
括号为匹配项提供一个列表上下文,for会一次将$_
设置为每个匹配项,并在每个匹配项上调用print "$_\n"
。
答案 3 :(得分:1)
这很容易。只需将所有匹配项保存在数组@x中:
perl -ne 'say join "\n",@x if @x=/\"resolution.(\w+)/g' FILE_NAME
@x不为空,则它将被if
评估为true。