perl在一行内获得最后N次匹配

时间:2014-09-02 22:15:21

标签: regex perl

我想从单行字符串$ a1中分别得到N + 1个部分,其中$ a1的第一部分包含字符,可能包含数字,逗号,单个空格或连续的多个空格。 而对于parts2到partN + 1只包含数字。

#       (part1)                     (part2)   (part3)  (part4)
my $a1=' adf  baifdhi ads 1882,  3   123       456     7';

$a1 =~ /^(.*)(\s+\d+){$N}$/;
$part1 = $1; (no problem here) 

但是如何才能将part2的数字转换为partN?似乎2美元只给了我最后一次比赛。 感谢

3 个答案:

答案 0 :(得分:2)

重复(...){5}的捕获组只会返回最后一个值。

要获取所有值,请在重复的表达式((?:...){5})周围使用捕获组,然后使用split

use strict;
use warnings;

#        (part1)                     (part2)   (part3)  (part4)
my $a1 = ' adf  baifdhi ads 1882,  3   123       456     7';
my $N  = 3;

if ($a1 =~ /^(.*)((?:\s+\d+){$N})$/) {
    my $part1 = $1;
    my @numbers = split ' ', $2;

    use Data::Dump;
    dd $part1;
    dd @numbers;
}

输出:

" adf  baifdhi ads 1882,  3  "
(123, 456, 7)

答案 1 :(得分:1)

如果要分割最后只包含十进制数字的字段,则可以使用split完成所有操作。喜欢这个

use strict;
use warnings;
use 5.010;

my $a1 = ' adf  baifdhi ads 1882,  3   123       456     7';

my @fields = split /\s+(?=[\d\s]+\z)/, $a1;

print "$_\n" for @fields;

<强>输出

 adf  baifdhi ads 1882,
3
123
456
7

答案 2 :(得分:0)

请注意,如果您在捕获组中使用多个匹配项,则只捕获捕获的最后一次迭代。

^(.*)(\s+\d+){3}$第二个联合组的示例' 7'

Demo

注意Regex101中的注释:

  

注意:重复捕获组仅捕获最后一次迭代。   在重复的组周围放置一个捕获组来捕获所有组   迭代或使用非捕获组,如果你不是   对数据感兴趣

如果现在将^(.*)((?:\s+\d+){3})$的此修改作为第二个捕获组,将重复模式放在非捕获组" 123 456 7"中,然后将整个组放入捕获(?:\s+\d+){3}

Demo

所以你的代码几乎正确:

((?:\s+\d+){3})

您还可以拆分这两部分:

use Data::Dump;

#       (part1)                     (part2)   (part3)  (part4)
my $a1=' adf  baifdhi ads 1882,  3   123       456     7';
my $N=3;

$a1 =~ /^(.*)((?:\s+\d+){$N})$/;

dd $1;
# " adf  baifdhi ads 1882,  3  "
dd $2;
# " 123       456     7"