2009-02-09 14 views
7

Tengo un programa Perl que almacena expresiones regulares en archivos de configuración. Ellos están en la forma:Doble interpolación de expresiones regulares en Perl

regex = ^/d+$ 

Por otra parte, la expresión regular se analiza desde el archivo y se almacena en una variable - $regex. Luego uso la variable al verificar la expresión regular, p. Ej.

$lValid = ($valuetocheck =~ /$regex/); 

Quiero ser capaz de incluir variables perl en el archivo de configuración, p. Ej.

regex = ^\d+$stored_regex$ 

Pero no sé cómo hacerlo.

Cuando las expresiones regulares son analizadas por Perl, se interpretan dos veces. Primero, las variables se expanden, y luego se analiza la expresión regular en sí misma.

Lo que necesito es un proceso de tres etapas: Primero interpola $regex, luego intercala las variables que contiene y luego analiza la expresión regular resultante. Ambas primeras interpolaciones deben ser "conscientes de la expresión regular". p.ej. deben saber que la cadena contiene $ como delimitador, etc. ...

¿Alguna idea?

Respuesta

3

El uso de eval puede ayudarlo aquí. Echar un vistazo al siguiente código que puede precompilar una expresión regular que está listo para ser utilizado este último: qr

my $compiled_regexp; 
my $regexp = '^\d+$stored_regexp$'; 
my $stored_regexp = 'a'; 

eval "\$compiled_regexp = qr/$regexp/;"; 
print "$compiled_regexp\n"; 

// El operador puede utilizar para precompilar una expresión regular. Te permite construirlo pero aún no lo ejecuta. Primero puedes construir tus expresiones regulares con ella y luego usarlas más tarde.

3

Sus variables de Perl no están dentro del alcance dentro de su archivo de configuración, y creo que eso es algo bueno. eval es aterrador.

Será mejor que implemente sus propias plantillas.

Así que en el fichero de configuración:

regex = ^\d+__TEMPLATE_FIELD__$ 

En el lector de archivos de configuración:

# something like this for every template field you need 
$regex =~ s/__TEMPLATE_FIELD__/$stored_regex/g; 

En el uso:

$lValid = ($valuetocheck =~ m/$regex/) 

Mover estos en todo dependiendo de en qué momento desea la sustitución de plantilla para aplicar.

7

Se puede definir la expresión regular en el archivo de configuración de la siguiente manera:

regex = ^\d+(??{$stored_regex})$ 

Pero tendrá que desactivar un control de seguridad en el bloque donde se utiliza la expresión regular al hacer esto en su programa de Perl:

use re 'eval'; 
+1

Es una solución elegante. –

0

Gotcha tangencialmente relacionado: Si hacer una doble línea de interpolación, y también tiene cadenas de sustitución de las variables, tenga en cuenta:

# the concat with doublequotes in the replacement string 
# are to make them PART OF THE STRING, NOT THE STRING DELIMITERS, 
# in other words, so the 2nd interpolation sees a double quoted string : 
#  eval eval $replace -> eval $1 hello world -> syntax error 
#  eval eval $replace -> eval "$1 hellow world" -> works ok 
# see: http://www.perlmonks.org?node_id=687031 

if($line =~ s/$search/'"' . $replace . '"'/ee) { 
    # STUFF... 
} 
Cuestiones relacionadas