2009-02-09 10 views
7

Ho un programma Perl che memorizza le espressioni regolari nei file di configurazione. Sono in forma:Doppia interpolazione delle espressioni regolari in Perl

regex = ^/d+$ 

Altrove, l'espressione regolare viene analizzato dal file e memorizzato in una variabile - $regex. Quindi uso la variabile quando si verifica la regex, ad es.

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

Voglio essere in grado di includere variabili perl nel file di configurazione, ad es.

regex = ^\d+$stored_regex$ 

Ma non riesco a capire come farlo.

Quando le espressioni regolari vengono analizzate da Perl, vengono interpretate due volte. Prima le variabili vengono espanse e quindi viene analizzata l'espressione regolare stessa.

Quello che mi serve è un processo a tre fasi: Prima interpolare $regex, quindi interpolare le variabili che contiene e quindi analizzare l'espressione regolare risultante. Entrambe le prime due interpolazioni devono essere "consapevoli dell'espressione regolare". per esempio. dovrebbero sapere che la stringa contiene $ come un'ancora ecc ...

Qualche idea?

risposta

3

Utilizzare eval può aiutarti qui. Date un'occhiata al seguente codice può precompilare un'espressione regolare che è pronto per essere utilizzato quest'ultimo:

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

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

L'operatore qr // può essere utilizzato per precompilare un regexp. Ti permette di costruirlo ma non lo esegue ancora. Puoi prima costruire le tue espressioni regolari con esso e poi usarle per ultime.

3

Le variabili Perl non sono comprese nell'ambito del file di configurazione e penso che sia una buona cosa. eval è spaventoso.

Sarebbe meglio implementare i propri modelli.

Così nel file di configurazione:

regex = ^\d+__TEMPLATE_FIELD__$ 

Nel lettore di file di configurazione:

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

Quando si utilizza:

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

spostare questi intorno a seconda di a che punto si desidera la sostituzione del modello da applicare.

7

È possibile definire il regexp nel file di configurazione in questo modo:

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

Ma è necessario disabilitare un controllo di sicurezza nel blocco in cui si sta utilizzando l'espressione regolare facendo questo nel vostro programma Perl:

use re 'eval'; 
+1

È una soluzione elegante. –

0

Un Gotcha tangenzialmente correlato: Se fare il doppio in linea di interpolazione, e hai anche le stringhe di sostituzione delle variabili, considerare:

# 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... 
}