如何使用多个捕获组的全局匹配?

时间:2015-03-15 08:08:26

标签: regex perl

我正在尝试在全局搜索中使用包含多个捕获组的正则表达式。正则表达式由用户输入,因此我不知道预先捕获组的数量。对于正则表达式的每个应用程序,我想将当前匹配存储在一个数组中。这是一个简单的例子:

use strict;
use warnings;
use Data::Dump;

my $str = 'Name: John Smith, Name: Bill Gates';

pos($str) = 0;
while (1) {

    #Note: the regex is not known at compile time
    my @a = $str =~ /\GName: (\w+) (\w+)/;
    dd @a;
    last if @a == 0; 
    pos($str) = $+[0];
}

然而,这不起作用。输出是:

  

(" John"," Smith")

预期输出为:

  

(" John"," Smith")
  (" Bill"," Gates")

3 个答案:

答案 0 :(得分:1)

似乎我忘记了.*?\G锚点跳到下一场比赛:

my @a = $str =~ /\G.*?Name: (\w+) (\w+)/;

答案 1 :(得分:0)

要在perl中使用全局正则表达式,您只需将“g”放在最后:$str =~ /REGEX/g;

所以你应该将正则表达式行改为my @a = $str =~ /Name: (\w+) (\w+)/g;,你应该得到你想要的结果。

答案 2 :(得分:0)

从包含可选逗号作为分隔符的输入字符串中,我已经使用这个简单的脚本获得了这个输出(“John Smith”,“Bill Gates”,“Mark Twain”):

use strict;
use warnings;
use Data::Dump;

my $str = 'Name: John Smith, Name: Bill Gates Name: Mark Twain';

my @person = split (/Name:/, $str);
my @a;

foreach (@person) { 
    s/\,//; # trim comma
    s/^\s+//; # trim leading space
    s/\s+$//; # trim trailing space
    s/Name:\s(\w+) (\[^,]+)/$1 $2/;
    if ($_ ne "") {push @a, $_;}
};

dd @a;