5

我想在文件中搜索字符串,然后获取所有匹配项的偏移量。文件内容如下:

sometext
sometext
AAA
sometext
AAA
AAA
sometext

我正在将整个文件读入一个字符串$text,然后进行正则表达式匹配,AAA如下所示:

if($text =~ m/AAA/g) {
    $offset = $-[0];
}

这将只给出一个偏移量AAA。我怎样才能得到所有比赛的抵消?

我知道我们可以使用如下语法获取数组中的所有匹配项:

my @matches = ($text =~ m/AAA/g);

但我想要偏移量不匹配的字符串。

目前我正在使用以下代码来获取所有匹配项的偏移量:

my $text= "sometextAAAsometextAAA";
my $regex = 'AAA';
my @matches = ();

while ($text =~ /($regex)/gi){
    my $match = $1;
    my $length = length($&);
    my $pos = length($`);
    my $start = $pos + 1;
    my $end = $pos + $length;
    my $hitpos = "$start-$end";
    push @matches, "$match found at $hitpos ";
}

print "$_\n" foreach @matches;

但是有没有更简单的方法呢?

4

2 回答 2

3

您已经知道应该使用$-[0]! 代替

while ($text =~ /($regex)/gi){
    my $match = $1;
    my $length = length($&);
    my $pos = length($`);
    my $start = $pos + 1;
    my $end = $pos + $length;
    my $hitpos = "$start-$end";
    push @matches, "$match found at $hitpos ";
}

while ($text =~ /($regex)/gi){
    push @matches, "$1 found at $-[0]";
}

也就是说,我非常喜欢将计算与输出格式分开,所以我会这样做

while ($text =~ /($regex)/gi){
    push @matches, [ $1, $-[0] ];
}

PS——除非你展开了一个while循环,否则if (/.../g)没有意义。充其量,/g什么都不做。更糟糕的是,你会得到不正确的结果。

于 2012-07-11T20:23:13.967 回答
2

我认为 Perl 中没有内置的方法可以做到这一点。但是从如何在 Perl 中找到正则表达式匹配的位置?

sub match_all_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /$regex/g) {
        push @ret, [ $-[0], $+[0] ];
    }
    return @ret
}
于 2012-07-11T19:37:41.177 回答