J'essaie de compter les caractères d'une chaîne et j'ai trouvé une solution facile à compter un seul caractère à l'aide de l'opérateur tr code>. Maintenant, je veux faire cela avec chaque personnage d'A à Z. La solution suivante ne fonctionne pas car
tr /// code> correspond à chaque caractère.
my @chars = ('a' .. 'z');
foreach my $c (@chars)
{
$count{$c} = ($text =~ tr/$c//);
}
6 Réponses :
mais il y a un moyen plus agréable de le faire: P > pour Timtowtdi: p> tr /// code> ne fonctionne pas avec des variables sauf si vous l'enveloppez dans un
eval code>
C'est une belle solution pour mon problème, mais cela ne répond pas à ma question comment utiliser la regex avec la variable. J'ai donc dû accepter les Eugènes. Pardon!
@ André: tr /// code> est pas i> une opération de regex, bien que la construction puisse sembler similaire
Notez que si l'un des caractères que vous recherchez est des métacaracters regex (comme . Code>,
? Code>,
* code>) au lieu de seulement az, vous besoin de leur échapper dans la première solution. Vous pouvez le faire en ajoutant
\ q code> à la regex:
$ comptez {$ _} = () = ~ / \ q $ _ / g pour '. ',' * '; code>
Ces deux méthodes ne sont pas tout à fait les mêmes. La première méthode (recherche de $ _ code>) produira un hachage avec 26 touches --- une pour chaque lettre de l'alphabet --- Peu importe si ces lettres apparaissent dans
$ texte code>. Le hachage produit par la deuxième méthode (en utilisant
grep code>) n'aura que des paires de clés pour les touches qui apparaissent dans
$ texte code>.
du Documentation Perlop :
foreach my $c (@chars) { $count{$c} += ($text =~ s/$c//g); }
Si vous regardez le perdoc pour Parce que la table de translittération est construite au moment de la compilation, ni la commande de la recherche ni la liste de remplacement ne sont soumises à une double interpolation de citation. Cela signifie que si vous souhaitez utiliser des variables, vous devez utiliser un eval (): p>
blockQuote> Ainsi, vous auriez donc besoin d'un eval pour générer une nouvelle déchets de recherche. P> Ceci va être très inefficace ... Le code pourrait être soigné , mais vous traitez la chaîne complète 26 fois. Vous ne comptez pas non plus de caractères majuscules. P> Vous seriez mieux à travers la chaîne une fois et incrémenter simplement des compteurs pour chaque personnage trouvé. P> P> tr / Gestion de la recherche / remplacement / CDSR CODE>, puis vous verrez, juste au bas de la section, les suivantes:
qui dit, une approche plus efficace (et sécurisée) serait de simplement itérer sur la Personnages dans la chaîne et les compteurs d'incrément pour chaque caractère, par exemple: p> TR code>
ne pas Soutenez l'interpolation variable (ni dans la liste de recherche ni dans la liste de remplacement). Si vous souhaitez utiliser des variables, vous devez utiliser eval () code>:
Cela fonctionne bien. Pourriez-vous expliquer pourquoi il y a une barre oblique contraire avant $ texte code>? Je suis nouveau à Perl :-)
André: Il empêche l'interpolation de la variable code> texte code> dans la chaîne, c'est-à-dire eval code> voit la chaîne comme
'$ text = ~ tr / a / a /' / code>
Ma solution avec une modification basée sur http://www.perlmonks.org/?node_id=446003
Vous pouvez utiliser ma solution: p> voir: p> s code> à la place. La substitution est beaucoup plus puissante que
tr code>
g code> à la fin signifie "l'utiliser globalement ". p>
Je ferais cela un peu différemment, vous pouvez remplacer n'importe quel caractère qui n'est pas quelque chose de [A-Z] avec rien et comptez les restes.
Je veux savoir combien il y a de chaque personnage, pas de la classe de caractère entière.
Maintenant, vous avez 2 problèmes? Y a-t-il une raison pour laquelle vous ne voulez pas simplement itérer via
$ texte code> et incrémenter la comptoir de chaque lettre comme vous le voyez?
À mon avis, le commentaire de WOOBLE est un moyen plus efficace de le faire que n'importe laquelle des réponses ci-dessous (alors j'ai donné un up :))
J'ai lu que
tr code> est beaucoup plus rapide que itérant sur le texte.
Merci pour toutes vos réponses rapides. J'ai voté pour Eugènes parce que c'est le plus simple et le plus proche de ce que je voulais.
@ André:
tr code> est sans aucun doute plus rapide que itérant lorsque vous remplacez un ensemble de caractères avec un autre. Faire 26
tr code> S, d'autre part, presque certainement ne sera certainement pas (bien que je n'ai pas été comparé).
D'accord avec @wooble. L'utilisation de cette approche est de loin une manière inefficace de le faire. De plus, vous manquez des caractères majuscules ici.
OK bon à savoir. Majuscule n'est pas un problème parce que j'ai fait un
LC () code> avant. Ne l'a pas posté parce que c'est sans importance ;-)