编译动态创建的regexp的简明方法

时间:2016-04-08 15:09:02

标签: regex perl

我想动态创建一个已编译的正则表达式。好吧,没问题:

my $rx = join('|', keys %replacement_hash);

我想编译它以避免重复调用的开销。没问题:

$rx = qr/$rx/;

虽然问题是什么 - 这种琐碎的操作太长了。两行和两次额外的时间我需要提到变量名,所以如果我决定重命名它,我需要在所有3个位置更改它。

到目前为止,我已经使用了一个辅助函数(它仍然具有必须在某处保留此函数的缺点):

sub qr_expr { qr/$_[0]/ }
# and later
my $rx = qr_expr(join('|', keys %replacement_hash));

或者只是简单地在我需要的地方插入相同的功能:

my $rx = sub{qr/$_[0]/}->(join('|', keys %replacement_hash));

有没有办法更简洁地写出来?

1 个答案:

答案 0 :(得分:3)

my ($re) = map qr/$_/, join '|', map quotemeta, @strings;

您可能无需编译它。

大多数情况下,您最终会将其嵌入到另一种模式中(例如/^$re\z//($re)/),从而强制重新编译模式。 (/$re/不会重新编译,等效的=~ $re也不会重新编译。)

此外,Perl缓存了它编译的最后一个模式的编译形式。如果要求再次编译相同的模式,则只返回缓存的副本。

在这两种情况下,以下就足够了:

my $pat = join '|', map quotemeta, @strings;