2009-10-21 11 views
4

Comment puis-je convertir une chaîne en une expression régulière qui lui correspond en Perl?Comment puis-je convertir une chaîne en une expression régulière qui lui correspond dans Perl?

J'ai un ensemble de chaînes comme celles-ci:

Enter your selection: 
Enter Code (Navigate, Abandon, Copy, Exit, ?): 

et je veux les convertir à des expressions régulières Sop je peux correspondre à autre chose contre eux. Dans la plupart des cas, la chaîne est le même que l'expression régulière, mais pas dans le second exemple ci-dessus parce que le (et avoir un sens dans les expressions régulières Alors que la deuxième chaîne doit être devenue une expression comme:.

Enter Code \(Navigate, Abandon, Copy, Exit, \?\): 

Je ne ai pas besoin la mise en correspondance trop stricte, donc quelque chose comme ça serait bien:

Enter Code .Navigate, Abandon, Copy, Exit, ..: 

Ma pensée actuelle est que je pourrais utiliser quelque chose comme:

s/[\?\(\)]/./g; 

bu t Je ne sais pas vraiment quels caractères figureront dans la liste des chaînes et si un caractère spécial me manque, je ne remarquerai peut-être jamais que le programme ne se comporte pas comme prévu. Et je pense qu'il devrait exister une solution générale.

Merci.

Répondre

18

Comme Brad Gilbert a commenté l'utilisation quotemeta:

my $regex = qr/^\Q$string\E$/; 

ou

my $quoted = quotemeta $string; 
my $regex2 = qr/^$quoted$/; 
+0

Génial, merci et merci à Brad. –

3

De http://www.regular-expressions.info/characters.html:

il y a 11 caractères avec une signification particulière: le crochet d'ouverture [, la barre oblique inverse \, le caret ^, le signe dollar $, la période ou un point ., la barre verticale ou symbole tuyau |, le point d'interrogation ?, l'astérisque ou étoile *, le signe plus +, la parenthèse d'ouverture ( et la parenthèse de fermeture )

En Perl (et PHP) il y a une fonction spéciale quotemeta qui échappera à tout cela pour vous.

+1

Ici ils sont tous juste à côté de l'autre au cas où vous souhaitez effectuer une classe de personnage hors de lui ou quelque chose. [\^$ | * +() – Tim

+0

Qu'en est '{}'? '$ foo = ~/a {1,4} /;' – daotoad

+1

En général, '{' et '}' ne sont pas spéciaux. Ils doivent apparaître dans une construction de correspondance de motif valide pour être spéciale. En tout cas, 'quotemeta' s'en chargera aussi. –

3

Pour mettre la suggestion de Brad Gilbert dans une réponse au lieu d'un commentaire, vous pouvez utiliser la fonction quotemeta. Tout le crédit pour lui

+1

All grêle Br ... Qui? –

3

Pourquoi utiliser une expression régulière? Puisque vous ne faites aucune capture et il semble que vous n'allez pas autoriser de variations, pourquoi ne pas simplement utiliser le index intégré?

$s1 = 'hello, (world)?!'; 
$s2 = 'he said "hello, (world)?!" and nothing else.'; 

if (-1 != index $s2, $s1) { 
    print "we've got a match\n"; 
} 
else { 
    print "sorry, no match.\n"; 
} 
+0

Je passe la regex à une fonction d'un module CPAN qui attend une regex, malheureusement. –

+0

Maintenant, c'est une très bonne raison d'utiliser une expression régulière. – innaM

7

Il existe une fonction pour cela quotemeta.

quotemetaEXPR
Renvoie la valeur de EXPR avec tous les caractères non "mot" antislash. (C'est, tous les caractères ne correspond pas à /[A-Za-z_0-9]/ sera précédée d'une barre oblique inverse dans la chaîne retournée , indépendamment des paramètres régionaux .) Ceci est la fonction interne qui implémente l'évasion \Q dans chaînes entre guillemets doubles. Si EXPR est omis, utilise $_.

Questions connexes