Angenommen, ich habe:
my $string = "one.two.three.four";
Wie soll ich mit dem Kontext spielen, um zu ermitteln, wie oft das Muster eine Übereinstimmung gefunden hat (3)? Kann dies mit einem Einzeiler erfolgen?
Ich habe es versucht:
my ($number) = scalar($string=~/\./gi);
Ich dachte, wenn ich Klammern setze $number
, würde ich den Array-Kontext erzwingen und durch die Verwendung von scalar
die Anzahl erhalten. Ich bekomme jedoch nur 1
.
() = $string =~ /\./gi
der Übereinstimmungsoperator die Ergebnisse der Übereinstimmung in einem Listenkontext zurückgeben. Dies ist ähnlich wiemy @results = $string =~ /\./gi;
. Als nächstes ist dasmy $number
Teil ein Skalarwert. Wenn Sie die Ergebnisse des Listenkontexts einem Skalar zuweisen, wird dessen Länge zurückgegeben. Dies ist dasselbe wiemy $count = @some_list
, was die Länge des Arrays zurückgibt. Meine Antwort unten ist eine andere Möglichkeit, das Verhalten hier zu visualisieren.Ich denke, der klarste Weg, dies zu beschreiben, wäre, die sofortige Umwandlung in Skalar zu vermeiden. Weisen Sie zuerst ein Array zu und verwenden Sie dieses Array dann im skalaren Kontext. Das ist im Grunde das, was die
= () =
Redewendung tun wird, aber ohne die (selten verwendete) Redewendung:my $string = "one.two.three.four"; my @count = $string =~ /\./g; print scalar @count;
quelle
@count
sind jedoch nicht erforderlich.Siehe auch Perlfaq4 :
quelle
Ist der folgende Code ein Einzeiler?
print $string =~ s/\./\./g;
quelle
Versuche dies:
my $string = "one.two.three.four"; my ($number) = scalar( @{[ $string=~/\./gi ]} );
Es kehrt
3
für mich zurück. Durch Erstellen einer Referenz auf ein Array wird der reguläre Ausdruck im Listenkontext ausgewertet und die@{..}
Referenzierung der Array-Referenz aufgehoben.quelle
Ich habe festgestellt, dass, wenn Sie eine ODER-Bedingung in Ihrem regulären Ausdruck haben (z. B.
/(K..K)|(V.AK)/gi
), das erzeugte Array möglicherweise undefinierte Elemente enthält, die am Ende in der Zählung enthalten sind.Zum Beispiel:
my $seq = "TSYCSKSNKRCRRKYGDDDDWWRSQYTTYCSCYTGKSGKTKGGDSCDAYYEAYGKSGKTKGGRNNR"; my $regex = '(K..K)|(V.AK)'; my $count = () = $seq =~ /$regex/gi; print "$count\n";
Gibt einen Wert von 6 an.
Ich habe die Lösung in diesem Beitrag gefunden. Wie entferne ich alle Undefs aus dem Array?
my $seq = "TSYCSKSNKRCRRKYGDDDDWWRSQYTTYCSCYTGKSGKTKGGDSCDAYYEAYGKSGKTKGGRNNR"; my $regex = '(K..K)|(V.AK)'; my @count = $seq =~ /$regex/gi; @count = grep defined, @count; my $count = scalar @count; print "$count\n";
Was dann die richtige Antwort von drei gibt.
quelle
ein anderer Weg,
my $string = "one.two.three.four"; @s = split /\./,$string; print scalar @s - 1;
quelle
my $count = 0; my $pos = -1; while (($pos = index($string, $match, $pos+1)) > -1) { $count++; }
mit Benchmark überprüft, ist es ziemlich schnell
quelle
Friedos Methode ist :
$a = () = $b =~ $c
.Aber es ist möglich, dies noch weiter zu vereinfachen
($a) = $b =~ $c
:my ($matchcount) = $text =~ s/$findregex/ /gi;
Sie können sich dafür bedanken, dass Sie dies einfach in eine Funktion einwickeln
getMatchCount()
und sich keine Sorgen machen, dass die übergebene Zeichenfolge dadurch zerstört wird.Auf der anderen Seite können Sie einen Swap hinzufügen, was zwar etwas aufwendiger ist, aber nicht zu einer Änderung der Zeichenfolge führt.
my ($matchcount) = $text =~ s/($findregex)/$1/gi;
quelle