it-swarm-eu.dev

Jak mohu najít umístění regex zápasu v Perlu?

Musím napsat funkci, která přijme řetězec a regex. Musím zkontrolovat, zda existuje shoda a vrátit počáteční a koncové místo zápasu. (Regex byl již kompilován qr//.)

Funkce může také obdržet "globální" příznak a pak musím vrátit (start, konec) páry všech zápasů.

Nemohu změnit regex, ani přidat () kolem něj, jak může uživatel použít () a \1. Možná můžu použít (?:).

Příklad: daný "ababab" a regex qr/ab/, v globálním případě musím získat 3 páry (start, end).

32
szabgab

Vestavěné proměnné @- a @+ drží počáteční a koncovou pozici posledního úspěšného zápasu. $-[0] a $+[0] odpovídají celému vzoru, zatímco $-[N] a $+[N] odpovídají podřízeným znakům $N ($1, $2, atd.).

72
Michael Carman

Zapomeňte na můj předchozí příspěvek, mám lepší nápad.

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
}

Tato technika v žádném případě nemění regex.

Upraveno pro přidání: do citace z perlvar na $ 1 .. $ 9. "Všechny tyto proměnné jsou jen pro čtení a dynamicky jsou přiřazeny k aktuálnímu bloku." Jinými slovy, pokud chcete použít $ 1 .. $ 9, nemůžete použít podprogram pro provedení párování.

19
Leon Timmermans

Funkce pos vám dává pozici zápasu. Pokud umístíte regex do závorek, můžete délku (a tím i konec) získat pomocí length $1. Takhle

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

Můžete také použít zastaralé proměnné $ `, pokud jste ochotni provádět všechny RE ve vašem programu pomaleji. Z perlvaru:

   $‘      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