Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Problema con backslashes

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Vie Jul 28, 2006 3:45 am
carlos
Perlero Nuevo
Perlero Nuevo
Registrado: 07 Abr 2005
Mensajes: 3
Problema con backslashes Responder citando

Hola a todos,

Leo de una base de datos un registro que contiene una cadena separada con backslashes '\' y guardo los valores de los subcampos en diferentes variables haciendo un split sobre la cadena. El problema que se me presenta es que cuando algunos subcampos no tienen valor alguno quedan seguidos 2 o mas backslashes y al tratarlos en perl uno de estos desaparece, puesto que perl lo toma como un escape al sigiuiente backslash. (interpolation)
No puedo modificar la cadena (var2) porque la leo de la base datos y no tengo(y no puedo) ninguna forma de modificar la base datos previamente.

Código:

use strict;
my ($var1, $var2, $a1, $b2, $c3, $d4, $e5);

# Todos los campos tienen un valor
$var1 = '11\22\33\44\55';  #Esto viene de la base datos y es inmodificable en la base de datos, pero una vez aqui si lo puedo modificar.

($a1,$b2,$c3,$d4,$e5) = split /\\/,$var1;

print "a1=$a1  b2=$b2  c3=$c3  d4=$d4  e5=$e5\n";
# Imprime:  a1=11  b2=22  c3=33  d4=44  e5=55


#Esto viene de la base datos y es inmodificable
#en la base de datos, pero una vez aqui si lo
#puedo modificar. El problema es que no se
#que backslash fue el que desaparecio.
# Por ejemplo, podría tener 11\\\\55 o \\33\\55 o 11\\\\ o ...

# Los campos 3 y 4 estan vacios
$var2 = '11\22\\\55'; 
($a1,$b2,$c3,$d4,$e5) = split /\\/,$var2;

print "a1=$a1  b2=$b2  c3=$c3  d4=$d4  e5=$e5\n";
# Imprime:  a1=11  b2=22  c3=  d4=55  e5=         # Indeseado  >-(
# Yo quiero que imprima
#  a1=11  b2=22  c3=  d4=  e5=55        <-- Deseado - esperado  :-)



Hay alguna forma de "corregir" este efecto por ahora indeseado?

Gracias por su atención.

Carlos Manuel
Mensaje Vie Jul 28, 2006 6:18 am
monoswim
Vive para Perl en Español
Vive para Perl en Español
Registrado: 18 Nov 2003
Mensajes: 720
Ubicación: Buenos Aires
Responder citando

No es recomendable tenés un campo en una base de datos cuyo contenido sena varios campos disitntos, mejor hacer otra tabla con esos campos y referenciarla...

Y luego con left join o inner join traes todo junto en variables separadas...Ahí te ahorrras muchos dolores de cabeza...

Saludos
PD: Sino intenta usar un separador que NUNCA aparezca como valor en los campos...
Mensaje Vie Jul 28, 2006 6:34 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4212
Ubicación: Valladolid, España
Responder citando

Supongamos que tenemos un fichero que representará la base de datos. Dentro de él, hay una línea como la siguiente:
Código:
11\22\\\55

Si ejecutamos el siguiente código:
Código:
#!/usr/bin/perl -l
while ( $var2 = <> ) {
    chomp $var2;            # Quitamos retorno de línea
    print $var2;            # Lo vemos antes..
    @a = split(/\\/,$var2); # Lo dividimos...
    print join("-",@a);     # La sacamos como queda...
}
así: perl programa.pl datos.txt, el resultado es el esperado:
Código:
11\22\\\55
11-22---55

Es decir, va todo bien.

¿Cuál es es el problema en tu código?

Resulta que en un programa en Perl, si pones algo entre comillas simples, se supone que Perl debe quedarse con todo ese texto de forma literal... PERO hay dos excepciones a esta regla: el backslash y la propia comilla, que es necesario escaparles.

Así, si tenemos '11\22\\\55', en principio podemos pensar que tenemos justo eso debido a las comillas simples, pero en realidad lo que tenemos es esto: '11\22\\55': un backslash ha desaparecido por haber sido 'escapado' por un hermano suyo. Y por esa razón tu ves en tu programa que entre el 22 y el 55 hay sólo un hueco. Split trabaja bien... no hace ni más ni menos de lo que tu le mandas.

Soluciones... como has visto, yo no he necesito hacer ninguna traducción de la entrada para dárselo diréctamente a split. Si hay algún problema como por ejemplo de que lo recibido es evaluado en algún momento y se pueden perder las barras, una forma de arreglarlo sería transformar esa barras inclinadas en otro carácter más amistoso:
Código:
#!/usr/bin/perl -l
while ( $var2 = <> ) {
    chomp $var2;            # Quitamos retorno de línea
    print $var2;            # Lo vemos antes..
    $var2 =~ tr/\\/|/;      # Transformación...
    print $var2;            # Lo vemos antes..
    @a = split(/\|/,$var2); # Lo dividimos...
    print join "-",@a       # La sacamos como queda...
}
con lo que sale:
Código:
11\22\\\55
11|22|||55
11-22---55
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group