¿Cómo manejo los caracteres especiales en una expresión regular de Perl?

Estoy usando un progtwig Perl para extraer texto de un archivo. Tengo una serie de cadenas que utilizo como delimitadores para el texto, por ejemplo:

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

Sin embargo, dos de las cadenas en el conjunto 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?

Prueba 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. Consulte perlretut para obtener más información sobre \Q y \E : es posible que no sean lo que está buscando.

quotemeta escapa de los metacaracteres, por lo que se interpretan como literales. Como atajo, puede usar \ Q … \ E en contexto de doble coz para rodear cosas que deberían citarse:

 $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 solo

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

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

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

aunque obviamente sucede después de la interpolación variable, por lo que “\ Q $ foo” no se convierte en ‘\ $ foo’.

Use quotemeta :

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