浅析PHP关键词替换的类(避免重复替换,保留与还原原始链接)


Posted in PHP onSeptember 22, 2015

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
 /* 
  * 关键词匹配类
  * @author ylx <ylx@gmail.com>
  * @packet mipang
  * 使用实例
  * $str = "绿壳蛋鸡撒范德萨下一年,下一年的洒落开房间卢卡斯地方军";
  * $key = new KeyReplace($str,array("xxxx"=>"sadf","下一年"=>'http://baidu.com',"下一年"=>'google.com'));
  * echo $key->getResultText();
  * echo $key->getRuntime();
  */
class KeyReplace
{
 private $keys = array();
 private $text = "";
 private $runtime = ;
 private $url = true;
 private $stopkeys = array();
 private $all = false;
 /**
  * @access public  
  * @param string $text 指定被处理的文章
  * @param array $keys 指定字典词组array(key=>url,...) url可以是数组,如果是数组将随机替换其中的一个
  * @param array $stopkeys 指定停止词array(key,...) 这里面的词将不会被处理
  * @param boolean $url true 表示替换成链接否则只替换
  * @param boolean $all true 表示替换所有找到的词,否则只替换第一次
  */
 public function __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;
 }
 /**
  * 获取处理好的文章
  * @access public  
  * @return string text
  */
 public function getResultText() {
  $start = microtime(true);
  $keys = $this->hits_keys();
  $keys_tmp = array_keys()($keys);
  function cmp($a, $b){
   if (mb_strlen($a) == mb_strlen($b)) {
 return ;
   }
   return (mb_strlen($a) < mb_strlen($b)) ? : -;
  }
  usort($keys_tmp,"cmp");
  foreach($keys_tmp as $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;
 }
 /**
  * 获取处理时间
  * @access public  
  * @return float 
  */
 public function getRuntime() {
  return $this->runtime;
 }
 /**
  * 设置关键词
  * @access public  
  * @param array $keys array(key=>url,...)
  */
 public function setKeys($keys) {
  $this->keys = $keys;
 }
 /**
  * 设置停止词
  * @access public  
  * @param array $keys array(key,...)
  */
 public function setStopKeys($keys) {
  $this->stopkeys = $keys;
 }
 /**
  * 设置文章
  * @access public  
  * @param string $text 
  */
 public function setText($text) {
  $this->text = $text;
 }
 /**
  * 用来找到字符串里面命中的关键词
  * @access public
  * @return array $keys 返回匹配到的词array(key=>url,...)
  */
 public function hits_keys(){
  $ar = $this->keys;
  $ar = $ar?$ar:array();
  $result=array();
  $str = $this->text;
  foreach($ar as $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();
 }
 /**
  * 用来找到字符串里面命中的停止词
  * @access public
  * @return array $keys 返回匹配到的词array(key,...)
  */
 public function hits_stop_keys(){
  $ar = $this->stopkeys;
  $ar = $ar?$ar:array();
  $result=array();
  $str = $this->text;
  foreach($ar as $k){
   $k = trim($k);
   if(!$k)
 continue;
   if(strpos($str,$k)!==false && in_array($k,$this->stopkeys)){
 $result[] = $k;
   }
  }
  return $result?$result:array();
 }
 /**
  * 处理替换过程 
  * @access private
  * @param string $text 被替换者
  * @param string $key 关键词
  * @param string $url 链接
  * @return string $text 处理好的文章
  */
 private function r_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",'<a href="'.$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($a as $n=>$at){
 $tmp = str_replace("[_a".$n."_]",$at,$tmp);
   }  
  }  
  if(!empty($tags)){
   foreach($tags as $n=>$at){
 $tmp = str_replace("[_tag".$n."_]",$at,$tmp);
   }  
  }  
  if(!empty($stopkeys)){
   foreach($stopkeys as $n=>$at){
 $tmp = str_replace("[_s".$n."_]",$at,$tmp);
   }  
  }  
  return $tmp;
 }
}

以上就是本文给大家介绍的PHP关键词替换的类(避免重复替换,保留与还原原始链接)。

PHP 相关文章推荐
数字转英文
Dec 06 PHP
php csv操作类代码
Dec 14 PHP
注册页面之前先验证用户名是否存在的php代码
Jul 14 PHP
JSON在PHP中的应用介绍
Sep 08 PHP
php curl基本操作详解
Jul 23 PHP
php验证session无效的解决方法
Nov 04 PHP
php返回相对时间(如:20分钟前,3天前)的方法
Apr 14 PHP
CodeIgniter实现从网站抓取图片并自动下载到文件夹里的方法
Jun 17 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
Sep 11 PHP
yii框架redis结合php实现秒杀效果(实例代码)
Oct 26 PHP
Yii使用DbTarget实现日志功能的示例代码
Jul 21 PHP
php双向队列实例讲解
Nov 17 PHP
PHP实现搜索相似图片
Sep 22 #PHP
从刷票了解获得客户端IP的方法
Sep 21 #PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
Sep 20 #PHP
分享ThinkPHP3.2中关联查询解决思路
Sep 20 #PHP
使用PHPCMS搭建wap手机网站
Sep 20 #PHP
求帮忙修改个php curl模拟post请求内容后并下载文件的解决思路
Sep 20 #PHP
PHP执行SQL文件并将SQL文件导入到数据库
Sep 17 #PHP
You might like
在mysql数据库原有字段后增加新内容
2009/11/26 PHP
PHP url 加密解密函数代码
2011/08/26 PHP
php变量作用域的深入解析
2013/06/03 PHP
解析PHP 5.5 新特性
2013/07/02 PHP
Linux系统下php获得系统分区信息的方法
2015/03/30 PHP
codeigniter实现get分页的方法
2015/07/10 PHP
PHP设计模式之单例模式定义与用法分析
2019/03/26 PHP
如何在Mozilla Gecko 用Javascript加载XSL
2007/01/09 Javascript
jQuery EasyUI API 中文文档 - Tabs标签页/选项卡
2011/10/01 Javascript
解析ScrollPic在ie8下只滚动一遍,然后变为空白 ie6,ie7,chrome,firefox正常
2013/06/26 Javascript
jquery()函数的三种语法介绍
2013/10/09 Javascript
jquery 通过name快速取值示例
2014/01/24 Javascript
javascript字符串循环匹配实例分析
2015/07/17 Javascript
js代码实现随机颜色的小方块
2015/07/30 Javascript
AngularJS使用ng-Cloak阻止初始化闪烁问题的方法
2016/11/03 Javascript
使用JavaScript进行表单校验功能
2017/08/01 Javascript
ReactNative Image组件使用详解
2017/08/07 Javascript
React-Native做一个文本输入框组件的实现代码
2017/08/10 Javascript
基于VUE.JS的移动端框架Mint UI的使用
2017/10/11 Javascript
如何使用vuex实现兄弟组件通信
2018/11/02 Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
2018/12/23 Javascript
package.json中homepage属性的作用详解
2020/03/11 Javascript
Python日期操作学习笔记
2008/10/07 Python
python查看zip包中文件及大小的方法
2015/07/09 Python
实现python版本的按任意键继续/退出
2016/09/26 Python
批量获取及验证HTTP代理的Python脚本
2017/04/23 Python
python实现字符串中字符分类及个数统计
2018/09/28 Python
python 多线程中子线程和主线程相互通信方法
2018/11/09 Python
两个元祖T1=('a', 'b'),T2=('c', 'd')使用匿名函数将其转变成[{'a': 'c'},{'b': 'd'}]的几种方法
2019/03/05 Python
使用Python正则表达式操作文本数据的方法
2019/05/14 Python
最新版 Windows10上安装Python 3.8.5的步骤详解
2020/11/28 Python
使用css3匹配手机屏幕横竖状态
2014/01/27 HTML / CSS
大学国际贸易专业自荐信
2014/06/05 职场文书
2015年工会工作总结
2015/03/30 职场文书
英语版自我评价,35句话轻松搞定
2019/10/08 职场文书
JavaScript+HTML实现学生信息管理系统
2021/04/20 Javascript