基本上,我有一系列关键字和一段文字。我想知道在文本中是否存在任何这些关键字的最佳方法是什么,同时考虑到性能问题。
我正在考虑循环遍历数组并为每个关键字执行strpos(),但是在数组中有超过一万个单词,需要花费一点时间来完成它,所以我想知道是否有一种更有效的方法。
答案 0 :(得分:2)
取决于字符串的大小您可以使用哈希来加快速度。
首先迭代文本。对于每个单词,将其分配给一个数组:
foreach (preg_split("/\s/", $text) as $word)
{
$string[$word] = 1;
}
然后迭代检查$ string的关键字:
foreach ($keywords as $keyword)
{
if (isset($string[$keyword]))
{
// $keyword exists in string
}
}
编辑 如果您的文字比关键字小得多,请向后搜索,检查文字中每个字词的关键字。如果文本非常短,这将比上面更快。
foreach (preg_split("/\s/", $text) as $word)
{
if (isset($keywords[$word]))
{
//might be faster if sizeof($text) < sizeof($keywords)
}
}
答案 1 :(得分:1)
假设格式化并且只关注是否存在任何(不是哪个)关键字,您可以尝试以下内容:
$keywords = array( "dog", "cat" );
// get a valid regex
$test = "(\b".implode( "\b)|(\b", $keywords )."\b)";
if( preg_match( $test, "there is a dog chasing a cat down the road" ) )
print "keyword hit";
答案 2 :(得分:1)
解决eWolf的想法......
foreach($keywords as &$keyword) {
$keyword = preg_quote($keyword);
}
$regex = "/(". implode('|', $keywords) .")/";
return preg_match($regex, $str);
如果您不想检查边界,则不必检查边界,但是如果您只使用\ b围绕组(()
字符),那么它只会匹配给定的单词。为了安全起见,你需要确保所有阵列的成员都是preg_quoted。
答案 3 :(得分:0)
我真的不知道它是否更有效率,但你可以尝试将它们全部放在这样的正则表达式中: (关键字1 |关键字2 | ...) 使用preg_quote函数,您可以转义正则表达式的关键字。如果设置编译选项,则将其与多个字符串一起使用可能会更有效。
答案 4 :(得分:0)
您可以将文本转储到数组中,并在两个数组上执行array_intersect_key。虽然我不确定这个表现......