2010-04-17 17 views
5

en Perl supongamos que tengo una cadena como 'hello\tworld\n', y lo que quiero es:¿Cómo puedo interpolar manualmente escapes de cadenas en una cadena Perl?

'hello world 
' 

es decir, "hola", a continuación, un carácter de tabulación literal, a continuación, "mundo", a continuación, una nueva línea literal. O de manera equivalente, "hello\tworld\n" (tenga en cuenta las comillas dobles).

En otras palabras, ¿hay una función para tomar una cadena con secuencias de escape y devolver una cadena equivalente con todas las secuencias de escape interpoladas? No quiero interpolar variables ni nada, solo escape secuencias como \x, donde x es una letra.

Respuesta

8

suena como un problema que otra persona tendría solved already. Nunca he usado el módulo, pero parece útil:

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

Muchas gracias por esto. Encontré String :: Interpolate, pero eso hace algo completamente diferente. –

+0

Además, para las personas que usan esto en Ubuntu 9.10, la versión de String :: Escape no tiene 'unbackslash'. En cambio, tiene 'no imprimible'. –

2

Usted puede hacerlo con 'eval':

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

en cuenta que hay problemas de seguridad vinculados a ese enfoque, si usted no tiene el control del 100% de la cadena de entrada.

Editar: Si desea interpolar SOLO sustituciones \ x (y no es el caso general de 'nada Perl interpolaría en una cadena entre comillas') que podría hacer esto:

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

que hace casi lo mismo cosa como quotemeta, pero exime a los '\' caracteres de ser escapados.

Edit2: Esto todavía no es 100% seguro, porque si el último carácter es un '\' - lo hará 'fuga' más allá del final de la cadena, aunque ...

Personalmente, si quería 100% seguro que haría un hash con los submarinos que quería específicamente y utilizar una sustitución de expresiones regulares en lugar de una eval:

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

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

¿Puedo utilizar una combinación de 'eval' y' quotemeta' para hacer esto de forma segura? Básicamente, '(mi $ interpolated_string = eval (q ("). Quotemeta ($ cadena). Q ("))) = ~ s/\\ (.)/\ 1/g'. –

+0

No sin que también se elimine la interpolación. ;) – Snowhare

+0

Bueno, solo quiero interpolar '\ x', donde' x' es cualquier letra. No variables u otras cosas. –

Cuestiones relacionadas