7

我有一个将正则表达式存储在配置文件中的 Perl 程序。它们采用以下形式:

regex = ^/d+$

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

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

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

regex = ^\d+$stored_regex$

但我不知道该怎么做。

当 Perl 解析正则表达式时,它们会被解释两次。首先展开变量,然后解析正则表达式本身。

我需要的是一个三阶段的过程:首先 interpolate $regex,然后插入它包含的变量,然后解析生成的正则表达式。前两个插值都需要“正则表达式感知”。例如,他们应该知道字符串包含$作为锚点等...

有任何想法吗?

4

4 回答 4

7

您可以像这样在配置文件中定义正则表达式:

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

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

use re 'eval';
于 2009-02-09T12:53:49.137 回答
3

在这里使用eval可以为您提供帮助。看看下面的代码,它可以预编译一个可以在后面使用的正则表达式:

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

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

运算符 qr// 可用于预编译正则表达式。它允许您构建它但尚未执行它。您可以先用它构建您的正则表达式,然后再使用它们。

于 2009-02-09T11:48:15.567 回答
3

您的 Perl 变量不在配置文件的范围内,我认为这是一件好事。评估是可怕的。

你最好实现自己的模板。

所以在配置文件中:

regex = ^\d+__TEMPLATE_FIELD__$

在配置文件阅读器中:

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

使用时:

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

根据您希望在什么时候应用模板替换来移动这些。

于 2009-02-09T11:48:53.287 回答
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... 
}
于 2010-04-09T21:19:04.190 回答