• Publicidad

Error comparación signo interrogación

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Error comparación signo interrogación

Notapor diazmunio » 2009-05-14 18:08 @797

Hola,

perdón si este no es el foro adecuado para mi pregunta, porque no sé si mi pregunta puede catalogarse de experto... pero es sobre expresiones regulares, así que ahí va.

En mi programa debo recorrer un array y comparar uno a uno los campos. Mi problema es que cuando ese campo contiene el signo '?' no me lo reconoce como parte de la cadena.

Para identificar el error he hecho un programa sencillo en el que asigno una cadena con '?' a una variable y hago la comprobación.

Ej.:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$cadena = "o no \?";
if ($linea =~ /\s($cadena)\s/)
{
   print $1; # imprime o no
}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Mi problema es que reconoce la expresión pero al imprimir $1 por pantalla me imprime la cadena sin el signo de interrogación.

Sin embargo si la comprobación la hago directamente con la cadena me imprime correctamente $1.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ($linea =~ /\s(o no \?)\s/)
{
   print $1; # imprime o no ?
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Alguna idea? He intentado corregir el fallo pero no veo la forma.

Muchas gracias.
diazmunio
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2009-05-14 17:50 @784

Publicidad

Notapor teco000 » 2009-05-14 18:44 @822

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$cadena = "o no \\?";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
teco000
Perlero nuevo
Perlero nuevo
 
Mensajes: 67
Registrado: 2008-05-29 15:22 @682
Ubicación: Guatemala

Muchas gracias

Notapor diazmunio » 2009-05-15 03:26 @185

¡¡¡¡¡¡Gracias!!!!!! Ya lo he probado y ¡funciona! ¡Me has salvado!
diazmunio
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2009-05-14 17:50 @784

Notapor explorer » 2009-05-15 03:49 @200

Bienvenido a los foros de Perl en Español, diazmunio.

Por lo que parece, has intentado "escapar" la función de '?' dentro de una cadena de caracteres.

Como regla general, no es necesario hacerlo.

Ahora bien, otra cosa es que esa cadena la vayamos a usar después como una expresión regular (o parte de).

Entonces, sí que es necesario hacer las correspondientes transformaciones a una expr. reg., y escapar el significado especial de '?'.

Ahora bien... hay que tener cuidado...

Primer ejemplo. Esto no funciona:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $linea  = 'esta sí, o esta no, ¿ o no ? ';
my $cadena = "o no \?";
print "[$cadena]\n";  # imprime "[o no ?]"
if ($linea =~ /\s($cadena)\s/)
{
   print "[$1]\n"; # imprime "[o no]"
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

es debido a que las comillas dobles provocan una interpolación de los caracteres que encierran, antes de hacer la asignación. Como hay una contrabarra delante del \? provoca que $cadena contenga 'o no ?'. La contrabarra filtra el posible carácter extraño que le sigue. Como lo que sigue es un carácter normal ('?' lo es), entonces, queda como está. Pero la barra desaparece. Fíjate en el primer print() cómo ha desaparecido.

Una solución es... evitar la interpolación, decir que la cadena de caracteres es tal cual la ponemos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $linea  = 'esta sí, o esta no, ¿ o no ? ';
my $cadena = 'o no \?';
print "[$cadena]\n";  # imprime "[o no \?]"
if ($linea =~ /\s($cadena)\s/)
{
   print "[$1]\n"; # imprime "[o no ?]"
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Y ya funciona, porque la contrabarra llega sin problemas a la expr. reg., haciendo que "escape" el significado especial de un '?', y tratándolo como un carácter normal. Por eso es capaz de capturar el trozo de texto de la $linea.

Otra forma... asegurarnos de que la cadena de caracteres que le pasamos a la expr. reg. no contiene caracteres especiales.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $linea  = 'esta sí, o esta no, ¿ o no ? ';
my $cadena = "o no ?";
print "[$cadena]\n";  # imprime "[o no ?]"
if ($linea =~ /\s(\Q$cadena\E)\s/)
{
   print "[$1]\n"; # imprime "[o no ?]"
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Con los caracteres especiales '\Q' y '\E' embutimos a $cadena, haciendo que todo carácter especial sea escapado. Esto tiene ventajas e inconvenientes: La ventaja es que no tenemos, nosotros, que acordarnos de escapar esos caracteres (mira el primer print()). Y la desventaja es que no podremos crear una verdadera exp. reg. en $cadena. Solo podremos tener ahí una cadena de caracteres. Si ponemos, por ejemplo, '[no]' para indicar que queremos buscar cualquier carácter 'n' u 'o', el efecto de '\Q' y '\E' será la de "escapar" a los corchetes, porque, en efecto, son especiales para una exp. reg.

Otra forma... decir, simple y claramente que estamos construyendo una exp. reg.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $linea  = 'esta sí, o esta no, ¿ o no ? ';
my $cadena = qr(o no \?);
print "[$cadena]\n";  # imprime "(?-xism:o no \?)"
if ($linea =~ /\s(\Q$cadena\E)\s/)
{
   print "[$1]\n"; # imprime "[o no ?]"
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El operador qr() transforma lo que contiene a una exp. reg. En este caso sí que tenemos que acordarnos de escapar a '?' porque lo estamos buscando de forma literal. Pero el refuerzo visual lo tenemos con la presencia de qr(): estamos ahora seguros que la razón de escapar a '?' es debido a que estamos construyendo una exp. reg.

Formas, hay muchas... elige la que te parezca más clara (visual y/o conceptualmente).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados