Perl中正则表达式的双重插值

8
我有一个Perl程序,它将正则表达式存储在配置文件中。它们的格式如下:
regex = ^/d+$

在其他地方,正则表达式从文件中解析并存储在变量$regex中。 然后我在检查正则表达式时使用该变量,例如。
$lValid = ($valuetocheck =~ /$regex/);

我想在配置文件中包含Perl变量,例如:
regex = ^\d+$stored_regex$

但我不知道如何做。
当Perl解析正则表达式时,它们会被解释两次。首先,变量会被扩展,然后正则表达式本身会被解析。
我需要的是一个三阶段过程:首先插值$regex,然后插值它包含的变量,最后解析生成的正则表达式。前两个插值都需要“正则表达式感知”。例如,它们应该知道字符串包含$作为锚点等...
有什么想法吗?
4个回答

7

您可以在配置文件中定义正则表达式,例如:

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

但是,在使用正则表达式的代码块中,您需要通过在Perl程序中执行以下操作来禁用安全检查:

use re 'eval';

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__$

在配置文件阅读器中:
# something like this for every template field you need
$regex =~ s/__TEMPLATE_FIELD__/$stored_regex/g;

在使用时:

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

根据您希望在何时应用模板替换的情况,移动它们。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接