2009-02-09 21 views
7

Ich habe ein Perl-Programm, das reguläre Ausdrücke in Konfigurationsdateien speichert. Sie sind in der Form:Doppelte Interpolation von regulären Ausdrücken in Perl

regex = ^/d+$ 

An anderer Stelle wird die Regex aus der Datei analysiert und in einer Variablen gespeichert - $regex. Ich verwende dann die Variable beim Überprüfen der Regex, z.

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

Ich möchte Perl-Variablen in der Konfigurationsdatei, z.

regex = ^\d+$stored_regex$ 

Aber ich kann nicht herausfinden, wie es geht.

Wenn reguläre Ausdrücke von Perl analysiert werden, werden sie doppelt interpretiert. Zuerst werden die Variablen erweitert, und dann wird der reguläre Ausdruck selbst analysiert.

Was ich brauche, ist ein dreistufiger Prozess: Zuerst interpolieren $regex, interpolieren Sie dann die Variablen und analysieren Sie dann den resultierenden regulären Ausdruck. Die beiden ersten Interpolationen müssen "reguläre Ausdrücke erkennen" sein. z.B. sie sollten wissen, dass die Zeichenkette $ als Anker usw. enthält.

Irgendwelche Ideen?

Antwort

3

Mit eval kann Ihnen hier helfen. Werfen Sie einen Blick auf den folgenden Code kann es eine regexp vorkompilieren, die letztere verwendet werden soll bereit ist:

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

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

Operator qr // kann verwendet werden, um einen regulären Ausdruck vorzukompilieren. Sie können es erstellen, aber noch nicht ausführen. Sie können zuerst Ihre Regexps damit erstellen und diese dann verwenden.

3

Ihre Perl-Variablen sind nicht in der Konfigurationsdatei enthalten, und ich denke, das ist eine gute Sache. eval ist unheimlich.

Sie wären besser dran, Ihre eigenen Vorlagen zu implementieren.

So in der Konfigurationsdatei:

regex = ^\d+__TEMPLATE_FIELD__$ 

In der Konfigurationsdatei Leser:

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

Bei Verwendung:

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

bewegen sich diese um je nach an welchem ​​Punkt Sie wollen die anzuwendende Vorlagensubstitution

7

Sie können die regexp in der Konfigurationsdatei wie folgt definieren:

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

Aber Sie müssen eine Sicherheitsüberprüfung in den Block deaktivieren, wo Sie die regexp verwenden durch dieses Programm in Perl zu tun:

use re 'eval'; 
+1

Es ist eine elegante Lösung. –

0

A tangential verwandte gotcha: Wenn Sie doppelte Interpolation Inline tun, und Sie auch Ersatz-Strings in Variablen haben, betrachten:

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