我尝试将第一组存储在@a1
中,将第二组存储在@a2
my $string = "abc123def456abc321def654";
my (@a1,@a2) = $string =~m/abc(\d+)def(\d+)/g;
$, = "\n";
print @a1;
结果为123 456 321 654
,然后@a2
为空。但我希望结果是@a1 = 123 321
; @a2 = 456 654
对于这个结果我尝试哈希,为了存储键是第一次分组,值是第二次分组但问题是重复删除。使用单个正则表达式匹配的任何可能的方法吗?
我在模式匹配中尝试了eval group
。我从@a1
得到了正确的结果,但@a2
出错了。而且不知道是什么问题?
my (@a1, @a2);
$string =~m/abc(\d+) (?{push @a1, $1}) def(\d+)(?{push @a2,$2 }) \G/x;
@a1
结果是
1234
321
666
@a2
结果是
4567
456
45
4
654
65
6
777
77
7
答案 0 :(得分:2)
你可以这样做:
use List::Util 'pairs';
my @a12 = pairs $string =~ /abc(\d+)def(\d+)/g;
my @a1 = map $_->[0], @a12;
my @a2 = map $_->[1], @a12;
或
use List::MoreUtils 'part';
my $i = 0;
my @part = part { $i++ % 2 } $string =~ /abc(\d+)def(\d+)/g;
my @a1 = @{ $part[0] };
my @a2 = @{ $part[1] };
或者只是跳过设置@ a1和@ a2并使用@ a12或@part中的数据。
答案 1 :(得分:1)
这就是你所追求的;
#!/usr/bin/env perl
use v5.12;
my $string = "abc123def456abc321def654";
my (@a1, @a2);
while ($string =~ /abc(\d+)def(\d+)/g) {
push @a1, $1;
push @a2, $2;
}
$, = "\n" ;
say @a1;
say @a2;
# Output
# 123
# 321
# 456
# 654
作为一般规则,尽量不要假设比赛成功。而不是直接赋值给变量,首先对匹配结果执行布尔测试('if'或'while),然后进行赋值。
答案 2 :(得分:1)
更新根据需求说明添加了一个在regex中完成所有操作的版本。
构建哈希:Key是模式(abc
,def
等),value是带有匹配项的数组引用。
my %h;
() = $string =~ /([a-z]+)(\d+)(?{push @{$h{$1}}, $2;})/g;
需要()
来强加列表上下文,因为否则只会发生第一次匹配,而/g
只会使其从匹配跳转到匹配。见perlrequick
。请注意,在匹配部分中运行代码是一项实验性功能。相反,您可以在替换部分中评估代码。
my %h;
$string =~ s/([a-z]+)(\d+)/{push @{$h{$1}}, $2}/eg;
这当然对原始字符串具有破坏性。
生成的散列具有作为模式(abc
,def
,...)的键,键值为array-ref,并且该键具有所有匹配项。您可以拥有任意数量的模式 - 数字对,而不仅仅是两个。见下文。
这两种变体的打印方式如下所示。
最初发布
这假设一种模式(您的abc
或def
)后跟数字。根据您的示例,此处使用的模式为[a-zA-Z]
。你可以拥有任意数量的这样的对,而不仅仅是两对。
use warnings;
use strict;
my $string = "abc123def456abc321def654";
my %h;
my $patt = qr/[a-zA-Z]/; # for example
push @{$h{$1}}, $2 while ($string =~ /($patt+)(\d+)/g);
print "$_ => @{$h{$_}}\n" for keys %h;
打印
def => 456 654 abc => 123 321
有两个以上的模式数字对(已添加ghi111
和ghi222
),
my $string = "abc123def456abc321ghi111def654ghi222";
# exactly the same code ...
打印
def => 456 654 abc => 123 321 ghi => 111 222
答案 3 :(得分:1)
我找到了问题的答案。我使用原子组并捕获结果。回溯是我的第二种情况的问题所以我使用原子组,有助于避免回溯。
$string =~m/abc(\d+)(?{push @a1, $1;})def(?>(\d+)) (?{ push @a2,$2; })\G/x;