2010-04-17 3 views
5

En Perl suppose que j'ai une chaîne comme 'hello\tworld\n', et ce que je veux est:Comment puis-je interpoler manuellement les échappements de chaînes dans une chaîne Perl?

'hello world 
' 

qui est, « bonjour », alors un caractère de tabulation littérale, puis « monde », puis un retour à la ligne littérale. Ou de manière équivalente, "hello\tworld\n" (notez les guillemets doubles). En d'autres termes, existe-t-il une fonction pour prendre une chaîne avec des séquences d'échappement et renvoyer une chaîne équivalente avec toutes les séquences d'échappement interpolées? Je ne veux pas interpoler des variables ou quoi que ce soit d'autre, juste des séquences d'échappement comme \x, où x est une lettre.

Répondre

8

ressemble à un problème que quelqu'un d'autre aurait solved already. Je n'ai jamais utilisé le module, mais il semble utile:

use String::Escape qw(unbackslash); 
my $s = unbackslash('hello\tworld\n'); 
+0

Merci beaucoup pour cela. J'ai trouvé String :: Interpolate, mais cela fait quelque chose de complètement différent. –

+0

De plus, pour les utilisateurs de Ubuntu 9.10, la version de String :: Escape n'a pas 'unbackslash'. Au lieu de cela, il a 'non imprimable». –

2

Vous pouvez le faire avec « eval »:

my $string = 'hello\tworld\n'; 
my $decoded_string = eval "\"$string\""; 

Notez qu'il ya des problèmes de sécurité liés à cette approche si vous ne disposez pas de contrôle à 100% de la chaîne d'entrée.

Edit: Si vous voulez seulement interpoler \ substitutions de x (et non pas le cas général de «quoi que ce soit Perl serait interpoler dans une chaîne entre guillemets), vous pouvez le faire:

my $string = 'hello\tworld\n'; 
$string =~ s#([^\\A-Za-z_0-9])#\\$1#gs; 
my $decoded_string = eval "\"$string\""; 

qui fait presque la même chose comme quotemeta - mais exempte les caractères '\' d'être échappé.

Edit2: Ce n'est pas encore 100% sûr parce que si le dernier caractère est un « \ » - il sera « fuite » après la fin de la chaîne mais ...

Personnellement, si je voulais 100% sûr que je ferais un hachage avec les sous-marins, je voulais spécifiquement et utiliser une substitution regex au lieu d'un eval:

my %sub_strings = (
    '\n' => "\n", 
    '\t' => "\t", 
    '\r' => "\r", 
); 

$string =~ s/(\\n|\\t|\\n)/$sub_strings{$1}/gs; 
+0

Puis-je utiliser une combinaison de 'eval' et' quotemeta' pour le faire en toute sécurité? Fondamentalement, '(my $ interpolated_string = eval (q ("). Quotemeta ($ chaîne). Q ("))) = ~ s/\\ (.)/\ 1/g'. –

+0

Pas sans lui aussi tuer l'interpolation. ;) – Snowhare

+0

Eh bien, je veux seulement interpoler '\ x', où' x' est n'importe quelle lettre. Pas de variables ou d'autres choses. –

Questions connexes