浅析PHP关键词替换的类(避免重复替换,保留与还原原始链接)
php关键词替换的类(避免重复替换,保留与还原原始链接)
本节主要内容:
一个关键词替换的类
主要可以用于关键词过滤,或关键词查找替换方面。
实现过程分析:
关键词替换,其实就是一个str_replace()的过程,如果是单纯的str_replace面对10W的关键词,1W字的文章也只需要2秒左右。
问题所在:
关键词替换了不只一次,比如a需要替换成<a>a</a>,但结果可能是<a><a>a</a></a>等这样。
为此,需要一个方法保护好已经替换了的标签,那么在处理文章之前,就先把标签替换掉比如[_tnum_]在文章处理好了以后再把它还原。
另外一个问题,如果关键字或文章中有[_tnum_]本身怎么办,那么就需要排除这种这里就不能使用str_replace了而需要用到preg_replace用正则来排除。
第三个问题,如果有两个关键字a和ab怎么办,希望先把长的匹配掉,短后匹配,这样就需要在匹配前先排序。
最后一个问题,当str_replace改成了preg_replace以后,变慢了同样一段话10W次匹配要5秒钟,字符串处理的函数中strpos要快一些,那么先用strpos找出关键词即可,10W次查询还不到1秒。就算是100万才道8秒多。
一个关键词匹配替换的类,代码:
代码示例:
<?php /* *关键词匹配类 *@authorylx<ylx@gmail.com> *@packetmipang *使用实例 *$str="绿壳蛋鸡撒范德萨下一年,下一年的洒落开房间卢卡斯地方军"; *$key=newKeyReplace($str,array("xxxx"=>"sadf","下一年"=>'http://baidu.com',"下一年"=>'google.com')); *echo$key->getResultText(); *echo$key->getRuntime(); */ classKeyReplace { private$keys=array(); private$text=""; private$runtime=; private$url=true; private$stopkeys=array(); private$all=false; /** *@accesspublic *@paramstring$text指定被处理的文章 *@paramarray$keys指定字典词组array(key=>url,...)url可以是数组,如果是数组将随机替换其中的一个 *@paramarray$stopkeys指定停止词array(key,...)这里面的词将不会被处理 *@paramboolean$urltrue表示替换成链接否则只替换 *@paramboolean$alltrue表示替换所有找到的词,否则只替换第一次 */ publicfunction__construct($text='',$keys=array(),$url=true,$stopkeys=array(),$all=false){ $this->keys=$keys; $this->text=$text; $this->url=$url; $this->stopkeys=$stopkeys; $this->all=$all; } /** *获取处理好的文章 *@accesspublic *@returnstringtext */ publicfunctiongetResultText(){ $start=microtime(true); $keys=$this->hits_keys(); $keys_tmp=array_keys()($keys); functioncmp($a,$b){ if(mb_strlen($a)==mb_strlen($b)){ return; } return(mb_strlen($a)<mb_strlen($b))?:-; } usort($keys_tmp,"cmp"); foreach($keys_tmpas$key){ if(is_array($keys[$key])){ $url=$keys[$key][rand(,count($keys[$key])-)]; }else $url=$keys[$key]; $this->text=$this->r_s($this->text,$key,$url); } $this->runtime=microtime(true)-$start; return$this->text; } /** *获取处理时间 *@accesspublic *@returnfloat */ publicfunctiongetRuntime(){ return$this->runtime; } /** *设置关键词 *@accesspublic *@paramarray$keysarray(key=>url,...) */ publicfunctionsetKeys($keys){ $this->keys=$keys; } /** *设置停止词 *@accesspublic *@paramarray$keysarray(key,...) */ publicfunctionsetStopKeys($keys){ $this->stopkeys=$keys; } /** *设置文章 *@accesspublic *@paramstring$text */ publicfunctionsetText($text){ $this->text=$text; } /** *用来找到字符串里面命中的关键词 *@accesspublic *@returnarray$keys返回匹配到的词array(key=>url,...) */ publicfunctionhits_keys(){ $ar=$this->keys; $ar=$ar?$ar:array(); $result=array(); $str=$this->text; foreach($aras$k=>$url){ $k=trim($k); if(!$k) continue; if(strpos($str,$k)!==false&&!in_array($k,$this->stopkeys)){ $result[$k]=$url; } } return$result?$result:array(); } /** *用来找到字符串里面命中的停止词 *@accesspublic *@returnarray$keys返回匹配到的词array(key,...) */ publicfunctionhits_stop_keys(){ $ar=$this->stopkeys; $ar=$ar?$ar:array(); $result=array(); $str=$this->text; foreach($aras$k){ $k=trim($k); if(!$k) continue; if(strpos($str,$k)!==false&&in_array($k,$this->stopkeys)){ $result[]=$k; } } return$result?$result:array(); } /** *处理替换过程 *@accessprivate *@paramstring$text被替换者 *@paramstring$key关键词 *@paramstring$url链接 *@returnstring$text处理好的文章 */ privatefunctionr_s($text,$key,$url){ $tmp=$text; $stop_keys=$this->hits_stop_keys(); $stopkeys=$tags=$a=array(); if(preg_match_all("#<a[^>]+>[^<]*</a[^>]*>#su",$tmp,$m)){ $a=$m[]; foreach($m[]as$k=>$z){ $z=preg_replace("#\##s","\#",$z); $tmp=preg_replace('#'.$z.'#s',"[_a".$k."_]",$tmp,); } }; if(preg_match_all("#<[^>]+>#s",$tmp,$m)){ $tags=$m[]; foreach($m[]as$k=>$z){ $z=preg_replace("#\##s","\#",$z); $tmp=preg_replace('#'.$z.'#s',"[_tag".$k."_]",$tmp,); } } if(!empty($stop_keys)){ if(preg_match_all("#".implode("|",$stop_keys)."#s",$tmp,$m)){ $stopkeys=$m[]; foreach($m[]as$k=>$z){ $z=preg_replace("#\##s","\#",$z); $tmp=preg_replace('#'.$z.'#s',"[_s".$k."_]",$tmp,); } } } $key=preg_replace("#([\#\(\)\[\]\*])#s","\\\\$",$key); if($this->url) $tmp=preg_replace("#(?!\[_s|\[_a|\[_|\[_t|\[_ta|\[_tag)".$key."(?!ag\d+_\]|g\d+_\]|\d+_\]|s\d+_\]|_\])#us",'<ahref="'.$url.'">'.$key.'</a>',$tmp,$this->all?-:); else $tmp=preg_replace("#(?!\[_s|\[_a|\[_|\[_t|\[_ta|\[_tag)".$key."(?!ag\d+_\]|g\d+_\]|\d+_\]|s\d+_\]|_\])#us",$url,$tmp,$this->all?-:); if(!empty($a)){ foreach($aas$n=>$at){ $tmp=str_replace("[_a".$n."_]",$at,$tmp); } } if(!empty($tags)){ foreach($tagsas$n=>$at){ $tmp=str_replace("[_tag".$n."_]",$at,$tmp); } } if(!empty($stopkeys)){ foreach($stopkeysas$n=>$at){ $tmp=str_replace("[_s".$n."_]",$at,$tmp); } } return$tmp; } }
以上就是本文给大家介绍的PHP关键词替换的类(避免重复替换,保留与还原原始链接)。