2009-02-23 12 views
7

Estoy usando un programa Perl para extraer texto de un archivo. Tengo una matriz de cadenas que utilizo como delimitadores para el texto, por ejemplo:¿Cómo manejo los caracteres especiales en una expresión regular de Perl?

$pat = $arr[1] . '(.*?)' . $arr[2]; 

if ($src =~ /$pat/) { 
    print $1; 
} 

Sin embargo, dos de las cadenas en la matriz son $450 y (Buy now). El problema con estos es que los símbolos en las cadenas representan el final de la cadena y el grupo de captura en las expresiones regulares de Perl, por lo que el texto no se analiza como lo pretendo.

¿Hay alguna forma de evitar esto?

Respuesta

11

Pruebe la función quotemeta de Perl. Alternativamente, use \Q y \E en su expresión regular para desactivar la interpolación de valores en la expresión regular. Ver perlretut para más información sobre \Q y \E - pueden no ser lo que estás buscando.

+0

Específicamente, \ Q no protegerá contra caracteres escapados de barra invertida. quotemeta es, de lejos, la solución más general. –

+2

@BenBlank: ¿De qué estás hablando? '\ Q' * se compila en *' quotemeta'. Ellos son la misma función. Del mismo modo, '\ L' compila en' lc', '\ U' en' uc', etc. '\ Q'" protege contra "caracteres de escape de barra invertida perfectamente, porque ** ¡es' \ Q' después de todo! ** – tchrist

4

Uso quotemeta:

$pat = quotemeta($arr[1]).'(.*?)'.quotemeta($arr[2]); 
if($src=~$pat) print $1; 
9

quotemeta escapa meta-caracteres para que se interpretan como literales. Como atajo, puede usar \ Q ... \ E en el contexto de doble quotish para rodear materia que debe ser citado:

$pat = quotemeta($arr[1]).'(.*?)'.quotemeta($arr[2]); 
if($src=~$pat) { print $1 } 

o

$pat = "\Q$arr[1]\E(.*?)\Q$arr[2]"; # \E not necessary at the end 
if($src=~$pat) { print $1 } 

o simplemente

if ($src =~ /\Q$arr[1]\E(.*?)\Q$arr[2]/) { print $1 } 

Tenga en cuenta que esto no está limitado a las variables interpoladas; caracteres literales están afectados también:

perl -wle'print "\Q.+?"' 
\.\+\? 

aunque obviamente que sucede después de la interpolación de variables, por lo que "\ Q $ foo" no se convierta en '\ $ foo'.

Cuestiones relacionadas