2011-09-14 34 views
6

Estoy tratando de hacer coincidir una expresión regular en Perl. Mi código es el siguiente:Escapar caracteres especiales en Perl regex

my $source = "Hello_[version]; Goodbye_[version]"; 
my $pattern = "Hello_[version]"; 
if ($source =~ m/$pattern/) { 
    print "Match found!" 
} 

El problema surge en ese paréntesis indican una clase de caracteres (o por lo que lee) cuando se trata de Perl que coincida con la expresión regular, y el partido acaba fracasando. Sé que puedo escapar de los corchetes con \[ o \], pero eso requeriría otro bloque de código para ir a través de la cadena y buscar los corchetes. ¿Hay alguna manera de hacer que los corchetes sean automáticamente ignorados sin escapar de ellos individualmente?

Nota rápida: No puedo simplemente agregar la barra invertida, ya que esto es solo un ejemplo. En mi código real, $source y $pattern provienen del código Perl (ya sea URIEncoded o de un archivo).

Respuesta

10

Está utilizando la herramienta incorrecta para el trabajo.

¡No tiene patrón! ¡NO hay caracteres regex en $ patrón!

Tiene una cadena literal.

índice() es para trabajar con cadenas literales ...

my $source = "Hello_[version]; Goodbye_[version]"; 
my $pattern = "Hello_[version]"; 
if (index($source, $pattern) != -1) { 
    print "Match found!"; 
} 
+0

+1 Para usar el índice() – sln

+0

¿Qué es exactamente un "carácter regex"? Tenía la impresión de que una expresión regular es solo un medio para unir cadenas o patrones en cadenas, no un conjunto específico de caracteres, a menos que haya otro significado para el que no tenga conocimiento. Aunque, gracias por el índice(). Daré una oportunidad cuando esté en mi servidor mañana; Creo que el índice() funcionará mejor y será más limpio que el ajuste de expresiones regulares. – CoV

+0

"carácter regex" era un error tipográfico, tenía la intención de escribir "metacaracter regex". – tadmc

11

Uso quotemeta():

my $source = "Hello_[version]; Goodbye_[version]"; 
my $pattern = quotemeta("Hello_[version]"); 
if ($source =~ m/$pattern/) { 
    print "Match found!" 
} 
11

\Q desactivará metacaracteres hasta \E se encuentra o el extremo del patrón.

my $source = "Hello_[version]; Goodbye_[version]"; 
my $pattern = "Hello_[version]"; 
if ($source =~ m/\Q$pattern/) { 
    print "Match found!" 
} 

http://www.anaesthetist.com/mnm/perl/Findex.htm

+0

Gracias sabía que era una solución sencilla, que funcionó a la perfección – CoV

+0

Cambiado mi "respuesta aceptada", lo siento, pero mientras la suya funcionó bien, creo que 'index()' era realmente lo que estaba buscando. ¡Gracias! – CoV

-1

citando a un $pattern en contra del propósito de las expresiones regulares a menos que sea utilizado como un conocido literal y se vierten en una expresión regular real.

edición
De lo contrario, sólo tiene que utilizar index() para encontrar la posición de la subcadena. Con esa información solo use substr() para extraer los datos circundantes si es necesario.

+0

use substr() para qué? – tadmc

+0

Usaría index() para obtener el posición, luego substr() (opcionalmente) para extraer datos residuales. – sln

0

se puede escapar de un conjunto de caracteres especiales en una expresión utilizando el siguiente comando.

expression1 = 'texto con caracteres especiales como $%()';

expression1 = ~ s/[\? * + \^\ $ [] \() {} \ | -]/"\ $ &"/eg;

Esto escapar todos los caracteres especiales

de impresión "expresión 1' ;! # Texto con caracteres especiales como \ $ \%()

Cuestiones relacionadas