我希望Perl检查字符串是否包含完全以逗号分隔的数字列表,然后将其拆分为数组。正则表达式/^(\d+)(?:,(\d+))*$/)
执行我想要的解析,但是当我在列表上下文中评估它时,我只得到第一个和最后一个数字。我尝试/(?:^|,)(\d+)(?=,|$)/g
使 g 修饰符发挥作用以发出多个匹配项,但这无法完全检查语法,如下例所示。那么我如何获得一个完全锚定的正则表达式,就像第一个发送一个多个匹配数组到()*
?
foreach (@ARGV) {
#if (my @numbers = /^(\d+)(?:,(\d+))*$/) {
if (my @numbers = /(?:^|,)(\d+)(?=,|$)/g) {
print "$_ = (@numbers)\n";
} else {
print "$_ isn't a number list!\n";
}
}
将上述内容放在名为numberlist.pl
的文件中并运行它,然后你会得到: -
bash$ perl numberlist.pl 1,2,3 ,1,2,3 1,2,3, a,2,3 1,b,3 1,2,c aa1,2,3zz
1,2,3 = (1 2 3)
,1,2,3 = (1 2 3)
1,2,3, = (1 2 3)
a,2,3 = (2 3)
1,b,3 = (1 3)
1,2,c = (1 2)
aa1,2,3zz = (2)
如果您取消注释第一个if
并对第二个进行评论,那么您会得到: -
1,2,3 = (1 3)
因此()
内(?:)
的内容会发出一个匹配项,而不是匹配列表。
我知道我可以使用第一个正则表达式检查语法,然后使用my @numbers = split /,/
来获取数组,但是有多种方法可以做到这一点。我只是不太清楚如何。救命啊!
答案 0 :(得分:0)
/^(?:\d+,)*\d+\z/ or die;
my @numbers = /\d+/g;
或
my @numbers = split /,/;
die if !@numbers;
for (@numbers) {
die if !/^\d+\z/;
}
答案 1 :(得分:0)
只需要正则表达式来过滤掉非数字。 split
在这里更有用:
for (@ARGV) {
next unless $_; # Add this to skip processing of blank entries.
my @l = grep {/^\d+\z/} split /,/;
print "$_ = (@l)\n";
}
正如所指出的,这会将空字符串视为空列表。这可能是也可能不是你想要的方式。
如果您不介意输入字符串末尾\n
的可能性,请将\z
更改回模式中的$
。
答案 2 :(得分:0)
我建议将验证与解析分开:
use strict;
use warnings;
local @ARGV = do {
no warnings 'qw';
qw(1,2,3 ,1,2,3 1,2,3, a,2,3 1,b,3 1,2,c aa1,2,3zz);
};
for (@ARGV) {
if (/^\d+(?:,\d+)*$/) {
my @numbers = split ',';
print "Numbers are @numbers\n";
} else {
print "NaN = $_\n";
}
}
输出:
Numbers are 1 2 3
NaN = ,1,2,3
NaN = 1,2,3,
NaN = a,2,3
NaN = 1,b,3
NaN = 1,2,c
NaN = aa1,2,3zz
但是,如果您已加入加入它们,那么请使用正向前瞻断言进行验证,然后像这样进行捕获:
for (@ARGV) {
if (my @numbers = /\G(?=\d+(?:,\d+)*$)(\d+),?/g) {
print "Numbers are @numbers\n";
} else {
print "NaN = $_\n";
}
}