给定一个查询,我想检查它是否包含给定的子字符串(可以包含多个单词)。但我不想进行详尽的搜索,因为这个子字符串只能开始一个新词。
任何用于此的perl标准库,以便我获得高效的东西,而不必重新发明轮子?
谢谢,
答案 0 :(得分:2)
也许你会发现内置index()
适合这项工作。
这是一个非常快速的子串搜索功能(实现了Boyer-Moore算法)。
只需使用perldoc -f index
检查其文档。
答案 1 :(得分:2)
我会使用键作为9000子串的第一个字,并且值为包含所有第一个字的子串的数组。如果许多字符串包含相同的第一个单词,则可以使用前两个单词。
然后对于每个查询,对于每个单词,我会看到该单词是否在散列中,然后需要仅匹配散列数组中的那些字符串,从字符串中的那个点开始使用索引函数。
假设匹配稀疏,这将非常有效。每个单词一次散列查找,最少搜索潜在匹配。
当我写这篇文章时,它让我想起了Aho-Corasick的搜索。 (参见CPAN中的Algorithm :: AhoCorasick。)我从未使用过该模块,但该算法花费了大量时间从搜索键中构建有限状态机,因此找到匹配是非常有效的。我不知道CPAN实现是否处理字边界问题。
答案 2 :(得分:1)
您可以使用此方法:
# init
my $re = join"|", map quotemeta, sort @substrings;
$re = qr/\b(?:$re)/;
# usage
while (<>) {
found($1) if /($re)/;
}
其中found
是动作,如果找到子字符串,你想做什么。
答案 3 :(得分:1)
内置index
函数是检查字符串是否包含子字符串的最快通用方法。
my $find = 'abc';
my $str = '123 abc xyz';
if (index($str, $find) != -1) {
# process matching $str here
}
如果index
仍然不够快,并且您知道子字符串可能位于字符串中的哪个位置,则可以使用substr
缩小范围,然后使用eq
进行实际操作比较:
my $find = 'abc';
my $str = '123 abc xyz';
if (substr($str, 4, 3) eq $find) {
# process matching $str here
}
如果不降低到C,你不会比Perl更快。
答案 4 :(得分:0)
这听起来像是regular expressions的完美工作:
if($string =~ m/your substring/) {
say "substring found";
} else {
say "nothing found";
}