Pregunta

Me está costando mucho determinar qué caracteres deben escapar al usar la construcción qr {} de Perl

Estoy intentando crear una expresión regular precompilada de varias líneas para el texto que contiene una miríada de caracteres que normalmente se escapan (# *. >: []) y también contiene otra expresión regular precompilada. Además, necesito coincidir 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.

Intentar escapar de los asteriscos da como resultado una coincidencia fallida (salida D'oh). Intentar escapar de otros personajes molestos también da como resultado un partido fallido. Podría seguir probando diferentes combos de qué escapar, pero hay muchas variaciones aquí y espero que alguien pueda proporcionar alguna información.

¿Fue útil?

Solución

Debe escapar del delimitador para qr //, y debe escapar de los metacaracteres regex que desee utilizar como literales. Si desea que sean literales *, debe escapar de ellos ya que * es un cuantificador de expresiones regulares.

Su problema aquí son los diversos indicadores de expresiones regulares que ha agregado. / M no hace nada porque no utiliza los anclajes de inicio o fin de cadena (^, $). El / s no hace nada porque no usa el comodín. metacarácter El / x hace que todo el espacio en blanco en su expresión regular no tenga sentido, y convierte esa línea con el # en un comentario de expresión regular.

Esto es lo que quieres, con las banderas de expresiones regulares eliminadas y las cosas correctas escapadas:

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 le dice a la gente en Perl Best Practices que siempre ponga estas opciones en sus expresiones regulares, ahora ve 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 puedes hacer si quieres usar / x. Debe escapar de cualquier espacio en blanco literal, debe denotar de alguna manera los finales de línea y debe escapar del carácter # literal. Lo que antes era legible 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";
}

Otros consejos

Parece que lo que realmente quieres es Espera , pero lo que lo que más se busca de inmediato es el operador quotemeta que escapa de todos los caracteres que tienen un significado especial para un expresiones regulares.

Para responder su pregunta directamente (sin embargo), además del carácter entre comillas (en este caso } ) debe escapar como mínimo, . [$ () | * + ? {\

Como dijo Brian, debes escapar del delimitador y los metacaracteres regex. Tenga en cuenta que cuando use qr // x (que es usted), también debe escapar de los espacios en blanco y # (que es un marcador de comentario). Probablemente no quieras usar / x aquí. Si quiere estar seguro, puede escapar de cualquier carácter no alfanumérico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top