【发布时间】:2010-10-31 11:31:38
【问题描述】:
有没有办法在 Perl 中预编译正则表达式?我有一个我在一个程序中多次使用它并且在使用之间不会改变。
【问题讨论】:
-
对于更一般的替换情况,使用包含正则表达式和替换的变量(例如,替换像
s/(\w+)/\u\L$1/g;(在变量/外部数据中),而不仅仅是变量中的固定字符串),请参阅@ 987654321@
标签: regex perl compilation
有没有办法在 Perl 中预编译正则表达式?我有一个我在一个程序中多次使用它并且在使用之间不会改变。
【问题讨论】:
s/(\w+)/\u\L$1/g;(在变量/外部数据中),而不仅仅是变量中的固定字符串),请参阅@ 987654321@
标签: regex perl compilation
使用 qr// 运算符(记录在 Regexp Quote-Like Operators 下的 perlop - Perl operators and precedence 中)。
my $regex = qr/foo\d/;
$string =~ $regex;
【讨论】:
对于文字(静态)正则表达式,没有什么可做的——Perl 只会编译一次。
if ($var =~ /foo|bar/) {
# ...
}
对于存储在变量中的正则表达式,您有几个选项。您可以使用qr// 运算符来构建一个正则表达式对象:
my $re = qr/foo|bar/;
if ($var =~ $re) {
# ...
}
如果您想在多个地方使用正则表达式或将其传递给子例程,这很方便。
如果正则表达式模式在字符串中,您可以使用/o 选项向 Perl 承诺它永远不会改变:
my $pattern = 'foo|bar';
if ($var =~ /$pattern/o) {
# ...
}
不过,通常最好不要这样做。 Perl 足够聪明,可以知道变量没有改变,也不需要重新编译正则表达式。指定/o 可能是过早的微优化。这也是一个潜在的陷阱。如果变量 has 使用/o 改变了会导致 Perl 使用旧的正则表达式。这可能会导致难以诊断的错误。
【讨论】:
/o 修饰符已被弃用。详情请见this question。
qr// 而不是仅在代码中使用正则表达式内联会使其速度降低 60% 以上!
为了澄清,您可以使用预编译的正则表达式:
my $re = qr/foo|bar/; # Precompile phase
if ( $string =~ $re ) ... # For direct use
if ( $string =~ /$re/ ) .... # The same as above, but a bit complicated
if ( $string =~ m/something $re other/x ) ... # For use precompiled as a part of a bigger regex
if ( $string =~ s/$re/replacement/ ) ... # For direct use as replace
if ( $string =~ s/some $re other/replacement/x ) ... # For use precompiled as a part of bigger regex, and as replace all at once
在perlre 中有记录,但没有直接的例子。
【讨论】:
$re 之后的下一个字符是+ 会发生什么