我正在使用cakephp 1.3,我有textarea用户提交文章。在提交时,我想查看文章中的某些关键词,并在文章中添加相应的标签。
我在考虑preg_match,但preg_match模式必须是字符串。所以我必须循环一个数组(大)。
是否有更简单的方法来插入模式的关键字数组。
感谢您的帮助。
感谢。
答案 0 :(得分:3)
我建议将关键字数组视为哈希表。小写文章文本,按空格分解,然后循环遍历爆炸数组的每个单词。如果哈希表中存在该单词,则将其推送到新数组,同时跟踪其被查看的次数。
在这种情况下,我运行了一个快速基准测试,将正则表达式与哈希表进行比较。要使用正则表达式运行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.然后,您可以执行该过程以确定要使用的标记。或者,如果您不关心关键字出现的次数,您可以跳过跟踪器部分,并在关键字出现时添加标签。
编辑:关键字数组可能需要是反向索引数组,以确保最快的查找。我不确定in_array()是如何工作的,但是如果它搜索的话,那就没那么快了。反向索引数组看起来像
array("computer" => 1, "dog" => 1, "sandwich" => 1); // "1" can be any value
然后你会做isset($ keywords [$ word])检查单词是否与关键字匹配,而不是in_array(),它应该给你O(1)。其他人可能会为我澄清这一点。
答案 1 :(得分:2)
当然,您可以尝试使用一个正则表达式匹配所有关键字,例如/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()
整个文字。
当然,确定哪种方法最好的唯一方法是设置一些测试,通过针对某些“代表性”和相当长的文本运行各种搜索功能并测量执行时间和资源使用情况(尝试{{1} }和microtime(TRUE)
对此进行基准测试。)
编辑:我清理了一些代码并添加了一个缺少的分号:)
答案 2 :(得分:2)
如果要从数组中查找多个单词,请将所述数组合并为正则表达式:
$regex_array = implode("|", array_map("preg_escape", $array));
preg_match_all("/($regex_array)/", $src, $tags);
这会将您的数组转换为/(word|word|word|word|word|...)/
。 arrray_map和preg_escape部分是可选的,仅在$ array 可能包含特殊字符时才需要。
在这种情况下避免使用strpos和循环。 preg_match可以更快地搜索替代品。
答案 3 :(得分:1)
如果您不需要正则表达式的强大功能,则应使用strpos()
。
您仍然需要遍历单词数组,但strpos
比preg_match
快得多。
答案 4 :(得分:0)
如果给出两个参数,则第二个 应该是表单中的数组 array('from'=>'到',...)。回报 value是一个所有的字符串 数组键的出现有 被相应的替换 值。将尝试最长的密钥 第一。一旦子串已经存在 换了,它的新价值不会 再次搜索。
答案 5 :(得分:0)
手动添加标签?就像我们在SO处添加标签一样。