你如何迫使Perl重新编译一个用"/ o"编译的正则表达式?

DVK*_*DVK 7 regex perl compilation modifier

技术问题:

鉴于正则表达式:

my $regEx = qr{whatever$myVar}oxi; # Notice /o for "compile-once"
Run Code Online (Sandbox Code Playgroud)

什么是迫使它按需重新编译的最有效方法?(例如,当我从程序逻辑中知道$myVar值已经改变时)没有掉线/o并依赖于Perl的内部智能来自动重新编译?

注意:正则表达式用于替换,这可能会影响重新编译规则sans/o:

$string2 =~ s/$regEx//;
Run Code Online (Sandbox Code Playgroud)

背景是:

  • 我有一个正则表达式,它是通过从配置文件中插入一个相当长(> 1k长)的字符串构建的.

    • 该文件每60分钟重新读取一次.

    • 如果从文件读取的字符串发生更改(通过更改文件时间戳定义),我想使用重新标记的字符串值重新编译正则表达式$myVar.

  • 在mod_perl下运行的Perl模块中重复使用正则表达式.

    • 这意味着(加上字符串长度> 1-2k)我必须使用" /o"修饰符强制在正则表达式上编译一次,以避免Perl的性能损失反复检查变量值是否发生变化(此启发式来自perlop qr//,自正则表达式用作s///上面所示的一部分,而不是作为匹配本身.

    • 这反过来意味着,当我知道变量在1小时内重新润滑后发生变化时,我需要强制正则表达式重新编译,尽管/o修饰符.

更新:这里是我需要的例子/o- 没有它,每次循环迭代都会重新编译正则表达式(因而必须检查); 它不是:

$ perl -e '{for (my $i=0; $i<3; $i++) {
                 my $re = qr{$i}oix; $s="123"; $s =~ s/$re//; 
                 print "i=$i; s=$s\n"; }}'
i=0; s=123
i=1; s=123
i=2; s=123

$ perl -e '{ for (my $i=0; $i<3; $i++) { 
                  my $re = qr{$i}ix; $s="123"; $s =~ s/$re//; 
                  print "i=$i; s=$s\n"; }}'
i=0; s=123
i=1; s=23
i=2; s=13
Run Code Online (Sandbox Code Playgroud)

ike*_*ami 4

当我从程序逻辑知道 $myVar 值发生变化时

m//s///并且qr// 只有在模式不改变的情况下才进行编译。要获得您所请求的行为,您所要做的就是删除/o.

$ perl -Mre=debug -e'
    qr/$_/ for qw( abc abc def def abc abc );
' 2>&1 | grep Compiling
Compiling REx "abc"
Compiling REx "def"
Compiling REx "abc"
Run Code Online (Sandbox Code Playgroud)

所以,

如果从文件中读取的字符串发生更改(通过更改文件时间戳来定义),我想使用 $myVar 中重新解析的字符串值重新编译正则表达式。
my $new_myVar = ...;
if ($myVar ne $new_myVar) {
   $re = qr/$new_myVar/;
   $myVar = $new_myVar;
}
...
s/$re/.../
Run Code Online (Sandbox Code Playgroud)

要不就

$myVar = ...;
...
s/$myVar/.../
Run Code Online (Sandbox Code Playgroud)