2009-02-09 7 views
7

Yapılandırma dosyalarında normal ifadeleri saklayan bir Perl programım var. Onlar şeklindedir:Perl'de normal ifadelerin çift enterpolasyonu

regex = ^/d+$ 

Başka bir yerde, regex dosyasından çözümlenmiş ve bir değişkene depolanır - $regex. Sonra regex'i kontrol ederken değişken kullanın, ör.

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

Yapılandırma dosyasında perl değişkenlerini içermek istiyorum, ör.

regex = ^\d+$stored_regex$ 

Ama nasıl yapılacağını bilemiyorum.

Düzenli ifadeler Perl tarafından ayrıştırıldığında, iki kez yorumlanır. İlk önce değişkenler genişletilir ve ardından normal ifadenin kendisi ayrıştırılır. İlk önce, $regex arasına sokmak içerdiği değişkenler interpole ve ardından ortaya çıkan normal ifadeyi ayrıştırmak: Ben gerekenler

üç aşamalı bir süreçtir. Hem ilk iki enterpolasyonun "düzenli ifadenin farkında olması" gerekir. Örneğin. dize, ankraj gibi $ içerdiğini bilmelidirler ...

Herhangi bir fikrin var mı?

cevap

3

eval'u kullanmak burada size yardımcı olabilir. ikincisi kullanılmaya hazır regexpi derleme aşağıdaki kodu bir göz atın:

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

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

operatör qr // regexpi derleme kullanılabilir. Bunu oluşturmanıza izin verir, ancak henüz yürütmez. İlk önce regex'lerinizi oluşturabilir ve daha sonra bunları kullanabilirsiniz.

3

Perl değişkenleriniz, yapılandırma dosyanızın içinde yer almıyor ve bence bu iyi bir şey. eval korkutucu.

Kendi şablonlarınızı uygulamaktan daha iyi olursunuz. yapılandırma dosyası okuyucu olarak

regex = ^\d+__TEMPLATE_FIELD__$ 

: yapılandırma dosyasında Yani

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

kullanarak:

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

Taşı bu çevrede hangi noktada istediğiniz de bağlı uygulanacak şablon değişimi.

Böyle yapılandırma dosyasında Regexp'i tanımlayabilirsiniz
7

:

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

Ancak, reklam Perl programda böyle yaparak Regexp'i kullandığınız bloğunda bir güvenlik denetimi devre dışı bırakmak gerekir:

use re 'eval'; 
+1

Zarif bir çözümdür. –

0

bir teğet ilgili yakaladım: çift enterpolasyon satır içi yapmak ve aynı zamanda değişkenleri değiştirme metinlerini varsa göz önünde bulundurun:

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