2008-11-14 19 views
5

estoy teniendo dificultades para determinar qué caracteres necesidad de escape al emplear QR de Perl {} construir¿Qué caracteres debo escapar en una expresión regular precompilada de Perl?

Estoy intentando crear una expresión regular precompilado para el texto de varias líneas que contiene una gran variedad de personajes normalmente escapado (# *.>: []) y también contiene otra expresión regular precompilada. Además, debo unir lo más estrictamente posible para fines de prueba.

my $output = q{# using defaults found in .config 
* 
* 
Options: 
    1. opt1 
> 2. opt2 
choice[1-2?]: }; 

my $sc = qr{(>|\s)}smx; 
my $re = qr{# using defaults found in .config 
* 
* 
Options: 
$sc 1. opt1 
$sc 2. opt2 
choice[1-2?]: }mx; 

if ($output =~ $re) { 
    print "OK!\n"; 
} 
else { 
    print "D'oh!\n"; 
} 

error:

Quantifier follows nothing in regex; marked by <-- HERE in m/# using defaults found in .config 
* <-- HERE 
* 
Options: 
(?msx-i:(>|\s)) 1. opt1 
(?msx-i:(>|\s)) 2. opt2 
choice[1-2?]:/at ./so.pl line 14. 

El intento de escapar de los resultados asteriscos en un partido fallado (D'oh salida). Intentar escapar de otros caracteres molestos también resulta en una coincidencia fallida. Podría seguir probando diferentes combos de qué escapar, pero hay muchas variaciones aquí y espero que alguien pueda darnos una idea.

Respuesta

14

Tienes que escapar del delimitador para qr //, y tienes que escapar de los metacaracteres de expresiones regulares que quieras usar como literales. Si quiere que esos sean literales *, necesita escapar de ellos ya que * es un cuantificador de expresiones regulares.

Su problema aquí son los diversos indicadores regex que ha agregado. El/m no hace nada porque no usa los anclajes de principio o final de cadena (^, $). El/s no hace nada porque no usas el comodín. metacarácter. El/x hace que todos los espacios en blanco en su expresión regular carezcan de sentido, y convierte esa línea con el # en un comentario de expresiones regulares.

Esto es lo que desea, con banderas de expresiones regulares retirados y las cosas adecuadas escaparon:

my $sc = qr{(>|\s)}; 

my $re = qr{# using defaults found in \.config 
\* 
\* 
Options: 
$sc 1\. opt1 
$sc 2\. opt2 
choice\[1-2\?]: }; 

Aunque Damian Conway dice a la gente en Perl Best Practices poner siempre estas opciones en sus expresiones regulares, que ahora ven por qué está equivocado Solo debe agregarlos cuando desee lo que hacen, y solo debe agregar cosas cuando sepa lo que hacen. :) Esto es lo que podrías hacer si quieres usar/x. Tienes que escapar de cualquier espacio en blanco literal, necesitas denotar los finales de línea de alguna manera, y tienes que escapar del carácter # literal. Lo que era legible antes de ahora es un desastre:

 
my $sc = qr{(>|\s)}; 
my $eol = qr{[\r\n]+}; 

my $re = qr{\# \s+ using \s+ defaults \s+ found \s+ in \s+ \.config $eol 
\*     $eol 
\*     $eol 
Options:    $eol 
$sc \s+ 1\. \s+ opt1 $eol 
$sc \s+ 2\. \s+ opt2 $eol 
choice\[1-2\?]: \s+ 
}x; 

if ($output =~ $re) { 
    print "OK!\n"; 
} 
else { 
    print "D'oh!\n"; 
} 
+0

Argh! Mi comprensión de lo que 's' y 'x' hicieron era inversa a la realidad. Por lo tanto, la 's' falta de $ re. Pero sí, culpo a PbP aquí también. :) –

+0

El libro explica qué hacen las opciones y por qué usarlas ... realmente no se puede culpar al libro por esto. :) –

+0

Puedo culpar al libro. Dice "Usar siempre el indicador/x" (p 236) y "Usar siempre el indicador/m" (p 237).La recomendación de "Siempre" es incorrecta. –

7

suena como lo que realmente quiere es Expect, pero lo que está más inmediatamente busca es el operador quotemeta que escapa a todos los caracteres que tienen un significado especial para una expresión regular.

Para contestar a su pregunta directamente (sin embargo), además del carácter fin de la cita (en este caso }) tiene que escapar como mínimo, .[$()|*+?{\

+0

En realidad, esto se está utilizando junto con Expect and Test :: More. Solo reduciendo el código para ejemplos sake. –

2

como Brian dijo, debe escapar de los meta-caracteres delimitadores y expresiones regulares . Tenga en cuenta que cuando usa qr//x (que lo es), también debe escapar de los espacios en blanco y # (que es un marcador de comentario). Probablemente no quiera usar /x aquí. Si quiere estar seguro, puede escapar de cualquier carácter no alfanumérico.

Cuestiones relacionadas