2009-10-20 62 views
1

基本上,我有一个关键字数组和一段文本。我想知道,考虑到性能问题,找出这些关键字是否存在于文本中是最好的方法。PHP - 查找数组中是否存在任何一个关键字

我正在考虑循环访问数组,并为每个关键字执行strpos(),但数组中有好几万个单词,需要PHP花一点时间才能完成,所以我想知道如果有更有效的方法来做到这一点。

+0

你能否提供一个字符串和数组的例子? – 2009-10-20 19:21:47

回答

2

取决于字符串的大小您可以使用散列使其更快。

首先迭代文本。对于每一个字,将其分配到一个数组:

foreach (preg_split("/\s/", $text) as $word) 
{ 
    $string[$word] = 1; 
} 

然后重复的关键字检查$字符串:

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) 
    } 
} 
+0

我发现了一个更好的方法来回答您的问题。将文本字符串分解为单独的单词,然后对每个单词查看它是否在数组中。使用in_array而不是strpos。我想知道这是否会更快。谢谢你,拜伦。 :) – 2009-10-20 19:36:28

+0

嘿,我想我们都在这里同时有AHAH时刻;)祝您好运 – 2009-10-20 19:38:02

+1

除了,如果您搜索每个单词,in_array会变得很慢。你真正想要的是二进制搜索。 – 2009-10-20 19:38:53

0

我真的不知道,如果它是更有效的,但你可以尝试把他们都在这样的正则表达式: (关键字1 |关键字2 | ...) 随着preg_quote功能,您可以逃脱的关键字为正则表达式。如果您设置了编译选项,将它与多个字符串一起使用可能会更有效。

+0

10,000个关键字会导致正则表达式分析器在整个地方都会出现漏洞。 – 2009-10-20 19:34:01

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"; 
+0

没有。超过10,000个关键字。 – 2009-10-20 19:39:21

+0

你说得对。但是这个问题在当时没有造成这样的大小;) – 2009-10-20 19:43:44

+0

是的。(查看修订历史记录) – 2009-10-20 20:58:44

0

,你可以放弃文本到一个数组中,并做了两个阵列上的array_intersect_key。我不知道这虽然表现的......

1

工作过eWolf的想法...

foreach($keywords as &$keyword) { 
    $keyword = preg_quote($keyword); 
} 

$regex = "/(". implode('|', $keywords) .")/"; 

return preg_match($regex, $str); 

您不必检查边界,如果你不想要,但如果你只是用\ b包围组(()个字符),然后它将只匹配给定的单词。为了安全起见,你需要确保所有数组的成员都是preg_quoted。

+1

超过10,000个关键字!!!!! – 2009-10-20 19:41:16

相关问题