如何实现PHP关键词替换的类(避免重复替换,保留与还原原始链接)

分类:PHP_Python| 发布:佚名| 查看:166 | 发表时间:2016/1/12

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秒多。

一个关键词匹配替换的类,代码:

代码示例:

001<?php
002 /*
003  * 关键词匹配类
004  * @author ylx <ylx@gmail.com>
005  * @packet mipang
006  * 使用实例
007  * $str = "绿壳蛋鸡撒范德萨下一年,下一年的洒落开房间卢卡斯地方军";
008  * $key = new KeyReplace($str,array("xxxx"=>"sadf","下一年"=>'http://baidu.com',"下一年"=>'google.com'));
009  * echo $key->getResultText();
010  * echo $key->getRuntime();
011  */
012class KeyReplace
013{
014 private $keys = array();
015 private $text = "";
016 private $runtime = ;
017 private $url = true;
018 private $stopkeys = array();
019 private $all = false;
020 /**
021  * @access public 
022  * @param string $text 指定被处理的文章
023  * @param array $keys 指定字典词组array(key=>url,...) url可以是数组,如果是数组将随机替换其中的一个
024  * @param array $stopkeys 指定停止词array(key,...) 这里面的词将不会被处理
025  * @param boolean $url true 表示替换成链接否则只替换
026  * @param boolean $all true 表示替换所有找到的词,否则只替换第一次
027  */
028 public function __construct($text='',$keys=array(),$url=true,$stopkeys=array(),$all=false) {
029  $this->keys = $keys;
030  $this->text = $text;
031  $this->url = $url;
032  $this->stopkeys = $stopkeys;
033  $this->all = $all;
034 }
035 /**
036  * 获取处理好的文章
037  * @access public 
038  * @return string text
039  */
040 public function getResultText() {
041  $start = microtime(true);
042  $keys = $this->hits_keys();
043  $keys_tmp = array_keys()($keys);
044  function cmp($a, $b){
045   if (mb_strlen($a) == mb_strlen($b)) {
046 return ;
047   }
048   return (mb_strlen($a) < mb_strlen($b)) ? : -;
049  }
050  usort($keys_tmp,"cmp");
051  foreach($keys_tmp as $key){
052   if(is_array($keys[$key])){
053 $url = $keys[$key][rand(,count($keys[$key])-)];
054   }else
055 $url = $keys[$key];
056   $this->text = $this->r_s($this->text,$key,$url);
057  }
058  $this->runtime = microtime(true)-$start;
059  return $this->text;
060 }
061 /**
062  * 获取处理时间
063  * @access public 
064  * @return float
065  */
066 public function getRuntime() {
067  return $this->runtime;
068 }
069 /**
070  * 设置关键词
071  * @access public 
072  * @param array $keys array(key=>url,...)
073  */
074 public function setKeys($keys) {
075  $this->keys = $keys;
076 }
077 /**
078  * 设置停止词
079  * @access public 
080  * @param array $keys array(key,...)
081  */
082 public function setStopKeys($keys) {
083  $this->stopkeys = $keys;
084 }
085 /**
086  * 设置文章
087  * @access public 
088  * @param string $text
089  */
090 public function setText($text) {
091  $this->text = $text;
092 }
093 /**
094  * 用来找到字符串里面命中的关键词
095  * @access public
096  * @return array $keys 返回匹配到的词array(key=>url,...)
097  */
098 public function hits_keys(){
099  $ar = $this->keys;
100  $ar = $ar?$ar:array();
101  $result=array();
102  $str = $this->text;
103  foreach($ar as $k=>$url){
104   $k = trim($k);
105   if(!$k)
106 continue;
107   if(strpos($str,$k)!==false && !in_array($k,$this->stopkeys)){
108 $result[$k] = $url;
109   }
110  }
111  return $result?$result:array();
112 }
113 /**
114  * 用来找到字符串里面命中的停止词
115  * @access public
116  * @return array $keys 返回匹配到的词array(key,...)
117  */
118 public function hits_stop_keys(){
119  $ar = $this->stopkeys;
120  $ar = $ar?$ar:array();
121  $result=array();
122  $str = $this->text;
123  foreach($ar as $k){
124   $k = trim($k);
125   if(!$k)
126 continue;
127   if(strpos($str,$k)!==false && in_array($k,$this->stopkeys)){
128 $result[] = $k;
129   }
130  }
131  return $result?$result:array();
132 }
133 /**
134  * 处理替换过程
135  * @access private
136  * @param string $text 被替换者
137  * @param string $key 关键词
138  * @param string $url 链接
139  * @return string $text 处理好的文章
140  */
141 private function r_s($text,$key,$url){
142  $tmp = $text;
143  $stop_keys = $this->hits_stop_keys();
144  $stopkeys = $tags = $a = array();
145  if(preg_match_all("#<a[^>]+>[^<]*</a[^>]*>#su",$tmp,$m)){
146   $a=$m[];
147   foreach($m[] as $k=>$z){
148 $z = preg_replace("#\##s","\#",$z);
149 $tmp = preg_replace('#'.$z.'#s',"[_a".$k."_]",$tmp,);
150   }
151  };
152  if(preg_match_all("#<[^>]+>#s",$tmp,$m)){
153   $tags = $m[];
154   foreach($m[] as $k=>$z){
155 $z = preg_replace("#\##s","\#",$z);
156 $tmp = preg_replace('#'.$z.'#s',"[_tag".$k."_]",$tmp,);
157   }
158  }
159  if(!empty($stop_keys)){
160   if(preg_match_all("#".implode("|",$stop_keys)."#s",$tmp,$m)){
161 $stopkeys = $m[];
162 foreach($m[] as $k=>$z){
163  $z = preg_replace("#\##s","\#",$z);
164  $tmp = preg_replace('#'.$z.'#s',"[_s".$k."_]",$tmp,);
165 }
166   }
167  }
168  $key = preg_replace("#([\#\(\)\[\]\*])#s","\\\\$",$key);
169  if($this->url)
170   $tmp = preg_replace("#(?!\[_s|\[_a|\[_|\[_t|\[_ta|\[_tag)".$key."(?!ag\d+_\]|g\d+_\]|\d+_\]|s\d+_\]|_\])#us",'<a href="'.$url.'">'.$key.'</a>',$tmp,$this->all?-:);
171  else
172   $tmp = preg_replace("#(?!\[_s|\[_a|\[_|\[_t|\[_ta|\[_tag)".$key."(?!ag\d+_\]|g\d+_\]|\d+_\]|s\d+_\]|_\])#us",$url,$tmp,$this->all?-:);
173  if(!empty($a)){
174   foreach($a as $n=>$at){
175 $tmp = str_replace("[_a".$n."_]",$at,$tmp);
176   
177  
178  if(!empty($tags)){
179   foreach($tags as $n=>$at){
180 $tmp = str_replace("[_tag".$n."_]",$at,$tmp);
181   
182  
183  if(!empty($stopkeys)){
184   foreach($stopkeys as $n=>$at){
185 $tmp = str_replace("[_s".$n."_]",$at,$tmp);
186   
187  
188  return $tmp;
189 }
190}
365据说看到好文章不转的人,服务器容易宕机
原创文章如转载,请注明:转载自郑州网建-前端开发 http://camnpr.com/
本文链接:http://camnpr.com/php-python/2225.html