我考虑使用preg_match,但preg_match模式必须是字符串。所以我不得不遍历一个数组(大型)。
有没有更简单的方法将关键字数组插入模式中?
感谢您的所有帮助。
谢谢。
我建议将您的关键字数组视为哈希表。将文章文本转换为小写,按空格分割,然后循环遍历每个单词。如果单词存在于哈希表中,则将其推送到一个新的数组中,并跟踪其出现次数。
我进行了一个快速基准测试,比较了在这种情况下使用正则表达式和哈希表的效果。使用正则表达式运行1000次需要17秒,而使用哈希表运行1000次只需要0.4秒。这应该是一个O(n+m)的过程。
$keywords = array("computer", "dog", "sandwich");
$article = "This is a test using your computer when your dog is being a dog";
$arr = explode(" ", strtolower($article));
$tracker = array();
foreach($arr as $word){
if(in_array($word, $keywords)){
if(isset($tracker[$word]))
$tracker[$word]++;
else
$tracker[$word] = 1;
}
}
$tracker 数组将输出: "computer" => 1, "dog" => 2。然后你可以进行处理来决定使用哪些标签。或者,如果你不关心关键词出现的次数,可以跳过 tracker 部分,当关键词出现时添加标签。array("computer" => 1, "dog" => 1, "sandwich" => 1); // "1" can be any value
那么你可以使用isset($keywords[$word])来检查单词是否匹配关键字,而不是使用in_array(),这样可以得到O(1)的复杂度。但其他人可能能更好地为我解释这个问题。
如果你想从数组中查找多个单词,则将该数组组合成正则表达式:
$regex_array = implode("|", array_map("preg_escape", $array));
preg_match_all("/($regex_array)/", $src, $tags);
/(word|word|word|word|word|...)/
。数组地图和preg_escape部分是可选的,只有在$array可能包含特殊字符时才需要。/word1|word2|word3/
,但我不确定这是否符合你的要求。而且我认为它会非常沉重和消耗资源。str_word_count()
,类似这样:$text = 'this is my string containing some words, some of the words in this string are duplicated, some others are not.';
$words_freq = array_count_values(str_word_count($text, 1));
将文本拆分为单词并计算出现次数。然后您可以使用 in_array($keyword, $words_freq)
或 array_intersect(array_keys($words_freq), $my_keywords)
进行检查。
如果您对关键字的大小写不敏感,可以在进行单词拆分之前使用 strtolower()
对整个文本进行转换。
当然,确定最佳方法的唯一方法是设置一些测试,通过运行各种搜索函数来测量执行时间和资源使用情况(尝试使用 microtime(TRUE)
和 memory_get_peak_usage()
进行基准测试)。
编辑:我清理了一下代码并添加了一个缺失的分号 :)
如果给定两个参数,则第二个参数应该是一个数组,形式为array('from' => 'to', ...)。返回值是一个字符串,其中所有数组键的出现都已被相应的值替换。最长的键将首先尝试。一旦替换了子字符串,它的新值就不会再次搜索。