例如,让我们假设我有一组变量和一组插入这些变量的正则表达式:
my ($var1,$var2,$var3); my @search_regexes=( qr/foo $var1/,qr/foo bar $var2/,qr/foo bar baz $var3/,);
上面的代码将告诉我们$var1,$var2和$var3没有在$search_regexes中的正则表达式的正则表达式编译时定义.但是,我想在这些正则表达式中延迟变量插值,直到实际使用它们为止(或者在变量具有值后稍后(重新)编译):
# Later on we assign a value to $var1 and search for the first regex in $_ ... $var1='Hello'; if (/$search_regexes[0]/) { # Do something ... }
我将如何在初始代码示例中重构构造以实现此目的?
作为奖励,我想在将值分配给该正则表达式中出现的相应变量之后编译每个正则表达式,其方式与qr //运算符现在正在执行的方式相同(但过早).如果您可以展示如何进一步扩展解决方案以实现这一点,我将非常感激.
更新:
我已经确定了Hunter方法的一个变种,因为使用它我不会受到性能影响,并且对现有代码的修改很少.其他答案也教会了我很多关于这个问题的替代解决方案及其在需要匹配很多行时的性能影响.我的代码现在类似于以下内容:
my ($var1,$var3); my @search_regexes=( sub {qr/foo $var1/},sub {qr/foo bar $var2/},sub {qr/foo bar baz $var3/},); ... ($var1,$var3)=qw(Hello there Mr); my $search_regex=$search_regexes[$based_on_something]->(); while (<>) { if (/$search_regex/) { # Do something ... # and sometimes change $search_regex to be another from the array } }
这让我得到了我正在寻找的代码,只需对我的代码进行最小的更改(即,只是在顶部添加了数组)并且每个正则表达式使用没有性能损失.
我想如果你将每个正则表达式包装在匿名子中,你可以做这种推迟:
my ($var1,$var3); my @search_regexes=( sub { return qr/foo $var1/ },sub { return qr/foo bar $var2/ },sub { return qr/foo bar baz $var3/ },);
然后,当你要评估它们时,你只需“呼叫”匿名子:
($var1,$var3) = qw(thunk this code); if( $_ =~ $search_regexes[0]->() ) { # Do something }
我知道在Scheme中这叫做thunking我不确定它是否在Perl中有一个名字.您可以使用Proc objects在Ruby中执行类似的操作