我有看起来像这样的大单词列表(此数据来自 db):
[
{
keyword => 'bmw.*red.*1999',
owner => 'someone'
#... other attributes
},
{
keyword => 'toyota.*black.*1999',
owner => 'someone else'
#... other attributes
},
# and so on ... up to 300 different keywords in a list
]
我必须定期将“关键字”与许多其他列表进行匹配。因为每次我将“关键字”编译为正则表达式时都会使用此关键字列表:
map { $_->{_compiled} = qr/$_->{keyword}/i } @keywords;
并将每个关键字与其他列表中的每个元素进行比较:
foreach my $other in (@other) {
foreach my $keword (@keywords) {
if ($other->{name} =~ $keyword->{_compiled}) {
## do something with $other and $keyword
}
}
}
这些操作应该每 10 分钟运行一次,并且应该有大约 50 个关键字列表(最多 300 个元素)和 50 个根据这些关键字检查的其他列表。它应该增长。
我想尽可能优化匹配速度,我有两个想法/问题:
将编译的正则表达式($keyword->{_compiled})保存在数据库中以供以后使用,但我不确定这有多大帮助(我没有做任何基准测试)
将所有“关键字”或“_compiled”加入一个大的正则表达式,并一步比较所有内容。
代码:
my @compiled = grep { $_->{_compiled} } @keywords;
# or is this better?
my $rx = "(".(join "|", grep { $_->{keyword} } @keywords).")";
my $compiled = qr/$rx/i;
foreach my $other in (@other) {
if ($other->{name} =~ @compiled) {
## do something with $other and $keyword
##
## but now there is no way to get "owner" of matched keyword
}
}
我的“问题”是我必须能够使用匹配关键字的“所有者”和其他属性。如果我在一个大的正则表达式中加入所有内容或将 _compiled 放入一个数组中,我将无法匹配
是否有“最佳解决方案”将大列表与大列表进行正则表达式比较?我什至不确定我是否应该担心性能问题,但列表会增加,我想做好准备。