У меня есть группа некоторых регулярных выражений и вы хотите совместить текущую строку для каждого из них, если совпадение получило вызов, вызовите некоторую функцию с сопоставленными группами в качестве параметров.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
первого предположения было удаление дополнительных регулярных выражений косых черт, в случае, . делает 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; просто строка, содержащая шаблон. Этот шаблон необходимо скомпилировать как Regex. – DavidO
... потому что хеш-ключи не могут быть ссылками (включая ссылки на объекты), они могут быть только неизменяемыми строками. – DavidO
Вероятно, вы должны настроить семантику вызова как нечто подобное: 'call_on_match ([[$ re_obj1 => \ & func1], [$ re_obj2 => \ & func2]]);' – DavidO