我有一些正則表達式的組,並且想爲它們中的每一個匹配當前行,如果匹配成功,調用一些具有匹配組作爲參數的函數。Perl,一組預編譯的正則表達式的匹配
my %regexps = (
"a" => qr/^(a)\s*(b)/o,
"b" => qr/^(c)\s*(d)/o,
"c" => qr/^(e)\s*(f)/o,
);
sub call_on_match {
my $actions = shift;
# ... some setup actions for $_
while (my ($regexp, $func) = each(%$actions)) {
if (my @matches = /$regexp/){
$func->(@matches);
}
}
}
call_on_match({
$regexps{"a"} => \&some_funca,
$regexps{"b"} => \&some_funcb,
$regexps{"c"} => \&some_funcc,
})
的問題是在my @matches = /$regexp/
表達時,它執行約110K倍和花費約1秒總編譯(此行的典型分析器輸出:# spent 901ms making 107954 calls to main::CORE:regcomp, avg 8µs/call
首先猜測是,以除去額外的regexp斜線,在情況下,它。令Perl認爲它是新的正則表達式,必須編譯我用my @matches = ($_ =~ $regexp)
,但沒有成功 是否有另一種辦法,使perl的不重新編譯qr'ed正則表達式在這種情況下
UPD:?我換成用哈希陣列(如[$regexps{"a"}, \&some_funca]
):
foreach my $group (@$actions){
my ($regexp, $func) = @$group;
if (my @matches = ($_ =~ $regexp)){
$func->(@matches);
}
}
現在它編譯更快,但編譯並沒有消失:# spent 51.7ms making 107954 calls to main::CORE:regcomp, avg 479ns/call
通過傳遞一個RegExp對象作爲匿名散列的關鍵字,它會串行化,並且不再是Regexp對象;只是一個包含模式的字符串。該模式將需要編譯爲正則表達式。 – DavidO
...因爲散列鍵不能被引用(包括對象的引用),它們只能是不可變的字符串。 – DavidO
你可能應該設置調用語義是這樣的:''call_on_match([[$ re_obj1 => \&func1],[$ re_obj2 => \&func2]]);' – DavidO