2012-02-11 9 views
8

J'ai une chaîne $regexp_as_stringPerl regexp comment échapper seulement quelques caractères

Maintenant, je veux « convertir » en un regex/l'utiliser comme regexp

if ($text_to_search =~ $regexp_as_string) 
{ 
... 
} 

Maintenant, il y a des personnages comme ». " et je veux leur échapper automaticly - \ Q et \ E devrait le faire

if ($text_to_search =~ /\Q$regexp_as_string\E/) 
    { 
    ... 
    } 

est-il un moyen de spécifier une liste de caractères qui doivent être auto échappé? Parce que pour l'instant, cette façon auto échappe par exemple "|" mais je veux garder ça.

Répondre

14

Vous pouvez préparer la chaîne à l'aide de quotemeta, puis supprimer les antislash sélectivement. .: par exemple

my $str = quotemeta('foo${}|'); 
$str =~ s/\\(?=[|])//g; 
say $str; 

Sortie:

foo\$\{\}| 

Ajoutez tous les caractères que vous voulez pas échappé à la classe de caractères dans la substitution, par exemple [|?()].

0

Peut-être au lieu de transmettre une chaîne jointe par | pour les alternances, obtenez la liste des alternances et construisez-les dans une chaîne (ou même les diviser par | si cela est garanti de ne jamais apparaître)? Quelque chose comme:

my @alternations = array_returning_function(); 
# my @alternations = split(/\|/, string_returning_function()); 
my $regexp_as_string = join('|', map(quotemeta, @alternations)); 

ou utiliser la fonction list2re de Data::Munge:

use Data::Munge; 
my @alternations = array_returning_function(); 
# my @alternations = split(/\|/, string_returning_function()); 
my $regexp_as_string = Data::Munge::list2re(@alternations); 
0

en utilisant par exemple la chaîne de TLP

my $str='foo${}|'; 
$str =~ s/([\.\{\}\$])/\\$1/g; 
print $str; 

Cela ne fera qu'ajouter une barre oblique inverse à des caractères qui sont les crochets "character class"

Notez que j'ai mis un caractère noir devant les caractères entre crochets. Ce n'est pas toujours nécessaire pour tous les personnages dans ce contexte, mais il est plus facile de simplement ajouter une barre oblique inverse et de ne pas vous en préoccuper.

+0

Correction: Il est plus facile de trouver les caractères que vous avez besoin d'échapper à l'intérieur d'une classe de caractères (les crochets) une fois pour toutes, et * puis * ne vous inquiétez pas: '-] \^$' sont les seuls les méta-caractères dont vous avez besoin de vous soucier, et même alors, c'est surtout dans la façon dont vous les utilisez. Par exemple: '[]]' et '[abc ^]' et '[a-z-]' vont bien. Voir http://perldoc.perl.org/perlrequick.html#Using-character-classes – TLP