web-dev-qa-db-ja.com

Perlで正規表現一致の場所を見つけるにはどうすればよいですか?

文字列と正規表現を受け取る関数を書く必要があります。一致があるかどうかを確認し、一致の開始位置と終了位置を返す必要があります。 (正規表現はすでにqr//によってコンパイルされています。)

関数は「グローバル」フラグも受け取る可能性があり、すべての一致の(開始、終了)ペアを返す必要があります。

ユーザーが()()を使用する可能性があるため、正規表現を変更することはできず、その周りに\1を追加することもできません。多分私は(?:)を使うことができます。

例:「ababab」と正規表現qr/ab/が与えられた場合、グローバルの場合、(開始、終了)の3つのペアを取得する必要があります。

32
szabgab

組み込み変数@-および@+は、最後に成功した一致の開始位置と終了位置をそれぞれ保持します。 $-[0]および$+[0]はパターン全体に対応し、$-[N]および$+[N]$N$1$2などに対応します。 。)サブマッチ。

72
Michael Carman

私の以前の投稿を忘れて、私はより良い考えを持っています。

sub match_positions {
    my ($regex, $string) = @_;
    return if not $string =~ /$regex/;
    return ($-[0], $+[0]);
}
sub match_all_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /$regex/g) {
        Push @ret, [ $-[0], $+[0] ];
    }
    return @ret
}

この手法は、正規表現をまったく変更しません。

追加するように編集:$ 1 .. $ 9でperlvarから引用する"これらの変数はすべて読み取り専用で、現在のBLOCKに動的にスコープされます。"つまり、$ 1 .. $ 9を使用する場合、サブルーチンを使用して照合を行うことはできません。

19
Leon Timmermans

Pos関数は、マッチの位置を示します。正規表現を括弧で囲んだ場合、length $1を使用して長さ(つまり、末尾)を取得できます。このような

sub match_positions {
    my ($regex, $string) = @_;
    return if not $string =~ /($regex)/;
    return (pos($string), pos($string) + length $1);
}
sub all_match_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /($regex)/g) {
        Push @ret, [pos($string), pos($string) + length $1];
    }
    return @ret
}
10
Leon Timmermans
#!/usr/bin/Perl

# search the postions for the CpGs in human genome

sub match_positions {
    my ($regex, $string) = @_;
    return if not $string =~ /($regex)/;
    return (pos($string), pos($string) + length $1);
}
sub all_match_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /($regex)/g) {
        Push @ret, [(pos($string)-length $1),pos($string)-1];
    }
    return @ret
}

my $regex='CG';
my $string="ACGACGCGCGCG";
my $cgap=3;    
my @pos=all_match_positions($regex,$string);

my @hgcg;

foreach my $pos(@pos){
    Push @hgcg,@$pos[1];
}

foreach my $i(0..($#hgcg-$cgap+1)){
my $len=$hgcg[$i+$cgap-1]-$hgcg[$i]+2;
print "$len\n"; 
}
0
Shicheng Guo

プログラム内のすべてのREの実行を遅くしたい場合は、廃止された$ `変数を使用することもできます。 perlvarから:

   $‘      The string preceding whatever was matched by the last successful pattern match (not
           counting any matches hidden within a BLOCK or eval enclosed by the current BLOCK).
           (Mnemonic: "`" often precedes a quoted string.)  This variable is read-only.

           The use of this variable anywhere in a program imposes a considerable performance penalty
           on all regular expression matches.  See "BUGS".
0
zigdon