5

ファイルで文字列を検索してから、すべての一致のオフセットを取得したいと思います。ファイルの内容は以下のとおりです。

sometext
sometext
AAA
sometext
AAA
AAA
sometext

このファイル全体を文字列に読み込んでから、次のよう$textに正規表現の一致を実行しAAAています。

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

これにより、1つのオフセットのみが得られ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 に答える