我想动态创建一个已编译的正则表达式。好吧,没问题:
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));
有没有办法更简洁地写出来?
答案 0 :(得分:3)
my ($re) = map qr/$_/, join '|', map quotemeta, @strings;
您可能无需编译它。
大多数情况下,您最终会将其嵌入到另一种模式中(例如/^$re\z/
或/($re)/
),从而强制重新编译模式。 (/$re/
不会重新编译,等效的=~ $re
也不会重新编译。)
此外,Perl缓存了它编译的最后一个模式的编译形式。如果要求再次编译相同的模式,则只返回缓存的副本。
在这两种情况下,以下就足够了:
my $pat = join '|', map quotemeta, @strings;