Ce que je veux faire, c'est vérifier un tableau de chaînes contre ma chaîne de recherche et obtenir la clé correspondante afin que je puisse le stocker. Y a-t-il une façon magique de le faire avec Perl, ou suis-je condamné à utiliser une boucle? Si tel est le cas, quel est le moyen le plus efficace de le faire?
Je suis relativement nouveau à Perl (je n'ai écrit que 2 autres scripts), donc je ne connais pas encore beaucoup la magie, mais que Perl est magique = d p>
4 Réponses :
update: strong> basé sur les résultats de la discussion dans Cette question , en fonction de votre intention / critère de ce qui constitue "ne pas utiliser de boucle", la solution code> basée sur la carte code> ci-dessous (voir « Option n ° 1 forte>) peut être la La plupart des solutions concises, à condition que vous ne considérez pas résultat de mon test: Sony Code> P> L'expression régulière (une fois la variable Cela ne fonctionnera pas comme si l'une des chaînes contienne des caractères spéciaux regex (tels que P.S. Pour obtenir "3" au lieu de "Sony", vous devrez utiliser une boucle - soit d'une manière évidente, en faisant 1 match dans une boucle sous tout le tout; Ou en utilisant une bibliothèque qui vous évite d'écrire la boucle vous-même mais que vous aurez une boucle sous l'appel. p> Je fournirai 3 solutions alternatives. P> # 1 Option: strong> - mon préféré. Utilise "Carte", que je considère personnellement une boucle: p> carte code> une boucle (la version courte des réponses est la suivante: c'est une boucle dans la mesure de la mise en œuvre / de la performance, ce n'est pas une boucle du point de vue théorique de la langue ). P>
| code>) à partir de la matrice, comme celui-ci: p>
combined_search code> est interpolée par Perl) Prenez le formulaire
/ (Canon | HP | HP | Sony) / code> qui est ce que vous voulez. p>
| code> ou
) code>) - dans ce cas dont vous avez besoin pour les échapper p>
joindre () code>, Perl lui-même doit faire une boucle quelque part à l'intérieur l'interpeter. Cette réponse peut donc ne pas satisfaire votre désir de rester en boucle, selon que vous souhaitiez éviter une boucle pour des considérations de performance, de disposer de code plus propre ou plus court. P>
my $found_index = -1;
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
foreach my $index (0..$#strings) {
next if $search_in !~ /$strings[$index]/;
$found_index = $index;
last; # quit the loop early, which is why I didn't use "map" here
}
# Check $found_index against -1; and if you want "3" instead of "2" add 1.
Merci pour cette réponse détaillée et informative: D Cette information est bien écrite et utile.
J'ai une autre question liée à cela. Je voudrais mettre en œuvre cela avec une gamme de valeurs 2 dimensions à la recherche, mais je ne suis pas sûr de savoir comment le faire avec aucune option 3. Suggestions à ce sujet? (J'ai édité la question de refléter le nouveau tableau)
@Ben - Vous voudrez peut-être le créer comme nouvelle question ... (lien avec celui-ci), afin que les gens puissent bénéficier en termes de recherche de la recherche.
Un moyen simple est d'utiliser un hachage et une regex:
while(my $search = <>) { #your $search is declared = to <> and now gets its values from STDIN or strings piped to this script }
L'OP spécifiquement indiqué "ou suis-je condamné à utiliser une boucle?" - Ce qui me semble-t-il comme s'il sait qu'il peut le faire dans une boucle et cherche une réponse non-boucle. Je pourrais me le lire mal
Voici une solution qui construit une expression régulière avec un code intégré pour incrémenter l'index comme Perl se déplace via la regex: la chaîne qui est achète à chaque marque d'abord l'index, puis essaie de faire correspondre la marque (échappée avec Lorsque la correspondance échoue, le moteur Regex passe au-delà de l'alternance Si vous avez plusieurs chaînes à correspondre, soyez Assurez-vous de réinitialiser quémététa code> (comme
\ q code>) pour permettre à des caractères spéciaux surgèrent dans les noms de marque). p>
| code>, puis le modèle se répète. p>
$ index code> avant chacun. Ou vous pouvez préparer
(? {$ Index = -1}) code> à la chaîne de regex. P> p>
Vous pouvez également jeter un coup d'œil à REGEXP :: Assemblez , qui sera Prenez une collection de sous-expulsions et construisez une seule super-regex à partir d'eux qui peut ensuite être utilisée pour les tester à la fois (et vous donne le texte qui correspondait au regex, bien sûr). Je ne suis pas sûr que ce soit la meilleure solution si vous regardez seulement trois cordes / expanses que vous souhaitez faire correspondre, mais c'est définitivement la voie à suivre si vous avez un ensemble ciblé sensiblement plus grand - le projet que je l'ai initialement utilisé sur A une bibliothèque de quelque 1500 termes qu'il correspond à une correspondance et qui fonctionne très bien. P>
Perl n'est pas vraiment magique. C'est juste un exemple de la technologie de pointe d'Arthur C. Clarke qui est indiscernable de la magie :) Puis encore, il y a tout ce formats que je considère personnellement vaudou :(
Quoi de neuf avec toute cette boucle déteste ces derniers temps? Si vous avez besoin de faire quelque chose sur une liste d'éléments, vous devez en faire la boucle en quelque sorte. Vous n'utilisez peut-être pas explicitement
pour code> ou
pendant code> mais à la fin de la journée, même la solution la plus ésotérique utilisera un cycle d'une sorte de tri.
@KEMP - Y avait-il d'autres questions anti-boucle récemment que j'ai manquées?