81 votes

Existe-t-il un raccourci Perl pour compter le nombre de correspondances dans une chaîne de caractères ?

Supposons que je l'ai fait :

my $string = "one.two.three.four";

Comment dois-je jouer avec le contexte pour obtenir le nombre de fois où le motif a trouvé une correspondance (3) ? Est-il possible de le faire en utilisant une ligne unique ?

J'ai essayé ça :

my ($number) = scalar($string=~/\./gi);

Je pensais qu'en mettant des parenthèses autour $number j'ai forcé le contexte du tableau, et par l'utilisation de scalar j'aurais le compte. Cependant, tout ce que j'obtiens est 1 .

124voto

friedo Points 36209

Cela place la regex elle-même dans un contexte scalaire, ce qui n'est pas ce que vous voulez. Au lieu de cela, mettez la regex dans un contexte de liste (pour obtenir le nombre de correspondances) et mettez que dans un contexte scalaire.

 my $number = () = $string =~ /\./gi;

4 votes

Eh bien, perlsecret propose "Saturne" comme nom alternatif. :)

1 votes

Quelqu'un peut-il m'expliquer ce bout de code ? Je suis nouveau en perl et je ne suis pas encore très à l'aise avec les contextes.

0 votes

La première partie, () = $string =~ /\./gi pour que l'opérateur de correspondance renvoie les résultats de la correspondance dans un contexte de liste. Ceci est similaire à my @results = $string =~ /\./gi; . Ensuite, le my $number est une valeur scalaire. En assignant les résultats du contexte de liste à un scalaire, on obtient sa longueur. C'est la même chose que my $count = @some_list qui renvoie la longueur du tableau. Ma réponse ci-dessous est une autre façon de visualiser le comportement ici.

35voto

Robert P Points 10807

Je pense que la manière la plus claire de décrire cela serait d'éviter la conversion instantanée en scalaire. Assignez d'abord à un tableau, et utilisez ensuite ce tableau dans un contexte scalaire. C'est en gros ce que fait le = () = L'idiome fera l'affaire, mais sans l'idiome (rarement utilisé) :

my $string = "one.two.three.four";
my @count = $string =~ /\./g;
print scalar @count;

15 votes

+1 pour la manière la plus directe, l'opérateur de chèvre est effrayant.

3 votes

Parenthèses autour @count sont cependant inutiles.

23voto

Robert P Points 10807

Voir aussi Perlfaq4 :

Il existe un certain nombre de moyens, dont l'efficacité varie. Si vous voulez compter un certain caractère unique (X) dans une chaîne, vous pouvez utiliser la fonction tr/// comme suit :

$string = "ThisXlineXhasXsomeXx'sXinXit";
$count = ($string =~ tr/X//);
print "There are $count X characters in the string";

C'est parfait si vous ne recherchez qu'un seul personnage. Cependant, si vous essayez de compter des sous-chaînes de plusieurs caractères dans une chaîne plus grande, tr/// ne fonctionnera pas. Ce que vous pouvez faire, c'est enrouler une boucle while() autour d'une correspondance de motif global. Par exemple, comptons les entiers négatifs :

$string = "-9 55 48 -2 23 -76 4 14 -44";
while ($string =~ /-\d+/g) { $count++ }
print "There are $count negative numbers in the string";

Une autre version utilise une correspondance globale dans un contexte de liste, puis assigne le résultat à un scalaire, produisant un compte du nombre de correspondances.

$count = () = $string =~ /-\d+/g;

9voto

Mike Points 990

Le code suivant est-il un "one-liner" ?

print $string =~ s/\./\./g;

7voto

PP. Points 6741

Essayez ça :

my $string = "one.two.three.four";
my ($number) = scalar( @{[ $string=~/\./gi ]} );

Il retourne 3 pour moi. En créant une référence à un tableau, l'expression régulière est évaluée dans le contexte de la liste et l'élément @{..} dé-référence la référence du tableau.

4 votes

Tu n'as pas besoin de ces parenthèses.

1 votes

Je dois dire que je préfère cette méthode à celle de la chèvre. En fait, j'aime à peu près tout mieux que le goatse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X