Comment puis-je échapper à la méta-caractères lorsque je interpoler une variable Perl opérateur de match?
Supposons que j'ai un fichier contenant des lignes je suis en train de match contre:
foo
quux
bar
Dans mon code, j'ai un autre tableau:
foo
baz
quux
Disons-nous parcourir le fichier, l'appel de chaque élément $word
, et la liste interne nous vérifions contre, @arr
.
if( grep {$_ =~ m/^$word$/i} @arr)
Cela fonctionne correctement, mais le peu possible de cas où nous avons un cas de test de fo.
dans le fichier, le .
fonctionne comme un opérateur générique dans la regex, et fo.
alors matches foo
, qui n'est pas acceptable.
C'est bien sûr parce que Perl est d'interpolation de la variable dans une expression régulière.
La question:
Comment puis-je la force de Perl pour utiliser la variable littéralement?
Voir stackoverflow.com/questions/1949731/...
double possible de Comment puis-je gérer les caractères spéciaux dans une expression rationnelle Perl?
Double Possible de Comment puis-je gérer les caractères spéciaux dans une expression rationnelle Perl?.
double possible de Comment puis-je gérer les caractères spéciaux dans une expression rationnelle Perl?
Double Possible de Comment puis-je gérer les caractères spéciaux dans une expression rationnelle Perl?.
OriginalL'auteur Paul Nathan | 2010-01-04
Vous devez vous connecter pour publier un commentaire.
La bonne réponse est - ne pas utiliser les expressions régulières. Je ne dis pas que les expressions régulières sont mauvais, mais les utiliser pour (ce qui est égal à) un simple contrôle d'égalité, c'est du matraquage.
Utilisation:
grep { lc($_) eq lc($word) } @arr
et d'être heureux.OriginalL'auteur
Utilisation
\Q...\E
pour échapper à des symboles spéciaux directement en perl chaîne après la valeur de la variable d'interpolation:$word = 'fo\E.'
?Puis regexp sera quelque chose comme "m/^fo\\E\\.$/j'". Voir
\Q
méta-symbole description sur perldoc.perl.org/perlfaq6.htmlPlus précisément, perldoc.perl.org/perlop.html#Quote-and-Quote-like-Operators note que
"abc\Qfoo\tbar$s\Exyz"
est équivalent à"abc" . quotemeta("foo\tbar$s") . "xyz"
.OriginalL'auteur Ivan Nevostruev
De perlfaq6's réponse à Comment puis-je rechercher une expression régulière dans une variable?:
Nous n'avons pas à coder en dur des motifs dans le match de l'opérateur (ou n'importe quoi d'autre qui fonctionne avec des expressions régulières). Nous pouvons mettre le modèle dans une variable pour l'utiliser plus tard.
L'opérateur de match est un guillemet double contexte, de sorte que vous pouvez interpoler votre variable comme une double chaîne de caractères entre guillemets. Dans ce cas, vous avez lu l'expression régulière comme la saisie de l'utilisateur et de les stocker dans $regex. Une fois que vous avez le rythme dans $regex, vous utilisez cette variable dans l'opérateur de match.
Toute expression régulière caractères spéciaux $regex sont toujours spécial, et le modèle doit encore être valide ou Perl va se plaindre. Par exemple, dans ce modèle il y a un impair parenthèse.
Lorsque Perl compile l'expression régulière, il traite de la parenthèse comme le début d'une mémoire de match. Quand il ne trouve pas la parenthèse fermante, il se plaint:
Vous pouvez contourner ce problème de plusieurs façons, selon notre situation. Tout d'abord, si vous ne voulez pas avoir des caractères dans la chaîne de l'être, vous pourrez vous évader avec quotemeta avant d'utiliser la chaîne de caractères.
Vous pouvez également le faire directement dans le match de l'opérateur à l'aide de l' \Q \E séquences. L' \Q indique à Perl par où commencer échapper les caractères spéciaux, et \E lui indique où à l'arrêt (voir perlop pour plus de détails).
Alternativement, vous pouvez utiliser les qr//, l'expression régulière citation de l'opérateur (voir perlop pour plus de détails). Il cite, et peut-être compile le modèle, et vous pouvez appliquer une expression régulière drapeaux pour le modèle.
Vous pouvez également intercepter des erreurs en les enveloppant d'un eval bloc autour de l'ensemble de la chose.
Ou...
L'eval va attraper toutes les erreurs dans son bloc, mais en termes de cette question, il est d'attraper une erreur dans le code explicite que vous voyez dans le match de l'opérateur.
OriginalL'auteur brian d foy
Quotemeta
Renvoie la valeur de EXPR avec tous les non-"mot" caractères backslashed.
http://perldoc.perl.org/functions/quotemeta.html
OriginalL'auteur Paul Nathan
Je ne pense pas que vous voulez un regex dans ce cas, puisque vous n'êtes pas correspondant à un motif. Vous êtes à la recherche d'un littéral de chaîne de caractères que vous connaissez déjà. Construire une table de hachage avec les valeurs de match et l'utiliser pour filtrer
@arr
:OriginalL'auteur brian d foy