2009-02-09 69 views
7

我有一個Perl程序,它在配置文件中存儲正則表達式。他們在形式:Perl中正則表達式的雙重插值

regex = ^/d+$ 

在其他地方,正則表達式從文件解析,並存儲在一個變量 - $regex。 然後,我在檢查正則表達式時使用該變量,例如

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

我希望能夠在配置文件中包含perl變量,例如,

regex = ^\d+$stored_regex$ 

但我不知道該怎麼做。

當Perl解析正則表達式時,它們會被解釋兩次。 首先擴展變量,然後解析正則表達式本身。

我需要的是一個三階段過程: 先插值$regex,然後內插它包含的變量,然後解析生成的正則表達式。 前兩個插值都需要「正則表達式意識」。例如他們應該知道該字符串包含$作爲錨等...

任何想法?

回答

3

使用eval可以幫助你在這裏。看看下面的代碼可以預編譯正則表達式這是隨時可以使用後者:

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

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

運營商QR //可用於預編譯正則表達式。它可以讓你建立它,但不執行它。你可以先用它構建你的正則表達式,然後使用它們。

3

你的Perl變量不在你的配置文件中,我認爲這是一件好事。 eval是可怕的。

你會更好地實施自己的模板。

regex = ^\d+__TEMPLATE_FIELD__$ 

在config文件中讀取:

在配置文件中

所以

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

使用:

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

移動這些圍繞取決於你想要什麼點應用模板替換。

7

您可以在配置文件中是這樣定義的正則表達式:

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

但你需要在你使用正則表達式在你的Perl程序做這其中塊禁用安全檢查:

use re 'eval'; 
+1

它是優雅的解決方案。 – 2009-02-09 13:02:02

0

切向相關的疑難雜症:如果你做雙插在線,你也有變量替換字符串,可以考慮:

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