自动生成文章摘要的代码[PHP 版本]


Posted in PHP onMarch 20, 2007

实现内容:截断一段含有HTML代码的文本,但是不会出现围堵标记没有封闭的问题。
说明:这是PHP版的,用于在服务器端使用,如果你需要一个客户端版的,请阅读下一篇 
我们在写BLOG这样的程序时经常需要显示文章前一部分的,但是又怕不恰当的截断破坏封闭标签以造成整个文档结构破坏,使用我的函数可以在要求不高的情况下解决这个问题。
大家应该考虑这个函数在服务端应用还是在客户端应用。因为我考虑这个函数可能运行起来比较费机器,所以安全性要求不高的情况下可以放在客户端上。
最好数据表中单独一个字段放这个摘要,这样相应的数据库查询也优化了。牺牲一点点空间换很多时间还是划算的。
再聊一下安全性问题,主要是内容安全性。如果客户端意图更改正常的摘要信息的话,一般都是BLOG的主人才有这个权力,那么他使得摘要和原文的一致性破坏就是他自己的事了。内容以外的安全性都可以在服务端解决。所以还是推荐在客户端使用本函数。
核心代码

// PHP 4.3 or above needed  
define("BRIEF_LENGTH", 800);     //Word amount of the Briefing of an Article  
function Generate_Brief($text){  
  global $Briefing_Length;  
  if(strlen($text) <= BRIEF_LENGTH ) return $text;     
  $Foremost = substr($text, 0, BRIEF_LENGTH);  
  $re = "/<(\/?)(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|OBJECT|A|UL|OL|LI|BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT|SPAN)[^>]*(>?)/i";  
  $Single = "/BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT/i";     
  $Stack = array(); $posStack = array();  
  preg_match_all($re,$Foremost,$matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);  
  /*   [Child-matching Specification]:  
    $matches[$i][1] : A "/" charactor indicating whether current "<...>" Friction is Closing Part  
    $matches[$i][2] : Element Name.  
    $matches[$i][3] : Right > of a "<...>" Friction   */  
  for($i = 0 ; $i < count($matches); $i++){  
    if($matches[$i][1][0] == ""){  
        $Elem = $matches[$i][2][0];  
        if(preg_match($Single,$Elem) && $matches[$i][3][0] !=""){  
          continue;  
        }  
        array_push($Stack, strtoupper($matches[$i][2][0]));  
        array_push($posStack, $matches[$i][2][1]);           
        if($matches[$i][3][0] =="") break;  
    }else{  
        $StackTop = $Stack[count($Stack)-1];  
        $End = strtoupper($matches[$i][2][0]);  
        if(strcasecmp($StackTop,$End)==0){  
          array_pop($Stack);  
          array_pop($posStack);  
          if($matches[$i][3][0] ==""){  
            $Foremost = $Foremost.">";  
          }  
        }  
    }       
  }  
  $cutpos = array_shift($posStack) - 1;     
  $Foremost = substr($Foremost,0,$cutpos);  
  return $Foremost;  
}; 
若遇到问题(发现上面的函数对多字节字符集支持得不好) 不烦试试下面的这个!
function Generate_Brief($text){  
  global $Briefing_Length;  
  mb_regex_encoding("UTF-8");  
  if(mb_strlen($text) <= BRIEF_LENGTH ) return $text;     
  $Foremost = mb_substr($text, 0, BRIEF_LENGTH);  
  $re = "<(\/?)(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|OBJECT|A|UL|OL|LI|BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT|SPAN)[^>]*(>?)";  
  $Single = "/BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT|BR/i";     
  $Stack = array(); $posStack = array();  
  mb_ereg_search_init($Foremost, $re, 'i');  
  while($pos = mb_ereg_search_pos()){  
    $match = mb_ereg_search_getregs();  
    /*   [Child-matching Formulation]:  
        $matche[1] : A "/" charactor indicating whether current "<...>" Friction is Closing Part  
        $matche[2] : Element Name.  
        $matche[3] : Right > of a "<...>" Friction     
    */  
    if($match[1]==""){  
        $Elem = $match[2];  
        if(mb_eregi($Single, $Elem) && $match[3] !=""){  
          continue;  
        }  
        array_push($Stack, mb_strtoupper($Elem));  
        array_push($posStack, $pos[0]);           
    }else{  
        $StackTop = $Stack[count($Stack)-1];  
        $End = mb_strtoupper($match[2]);  
        if(strcasecmp($StackTop,$End)==0){  
          array_pop($Stack);  
          array_pop($posStack);  
          if($match[3] ==""){  
            $Foremost = $Foremost.">";  
          }  
        }  
    }  
  }  
  $cutpos = array_shift($posStack) - 1;     
  $Foremost = mb_substr($Foremost,0,$cutpos,"UTF-8");  
  return $Foremost;  
}; 
PHP 相关文章推荐
PHP Google的translate API代码
Dec 10 PHP
浅析PHP递归函数返回值使用方法
Feb 18 PHP
解析phpstorm + xdebug 远程断点调试
Jun 20 PHP
关于php操作mysql执行数据库查询的一些常用操作汇总
Jun 24 PHP
php防止伪造的数据从URL提交方法
Jun 27 PHP
php实现给图片加灰色半透明效果的方法
Oct 20 PHP
php实现可用于mysql,mssql,pg数据库操作类
Dec 13 PHP
PHP中使用xmlreader读取xml数据示例
Dec 29 PHP
php实现购物车功能(下)
Jan 05 PHP
php 将json格式数据转换成数组的方法
Aug 21 PHP
Laravel5.7 Eloquent ORM快速入门详解
Apr 12 PHP
Yii框架通过请求组件处理get,post请求的方法分析
Sep 03 PHP
关于BIG5-HKSCS的解决方法
Mar 20 #PHP
php中支持多种编码的中文字符串截取函数!
Mar 20 #PHP
理解PHP5中static和const关键字的区别
Mar 19 #PHP
php中目录,文件操作详谈
Mar 19 #PHP
PHP配置文件中最常用四个ini函数
Mar 19 #PHP
推荐一篇入门级的Class文章
Mar 19 #PHP
隐藏你的.php文件的实现方法
Mar 19 #PHP
You might like
php下判断数组中是否存在相同的值array_unique
2008/03/25 PHP
php中转义mysql语句的实现代码
2011/06/24 PHP
php启用sphinx全文搜索的实现方法
2014/12/24 PHP
php简单实现MVC
2015/02/05 PHP
1亿条数据如何分表100张到Mysql数据库中(PHP)
2015/07/29 PHP
PHP实现微信小程序人脸识别刷脸登录功能
2018/05/24 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
php计数排序算法的实现代码(附四个实例代码)
2020/03/31 PHP
JMenuTab简单使用说明
2008/03/13 Javascript
seajs中模块的解析规则详解和模块使用总结
2014/03/12 Javascript
jQuery实现checkbox全选的方法
2015/06/10 Javascript
使用jQuery Ajax 请求webservice来实现更简练的Ajax
2016/08/04 Javascript
javascript实现将数字转成千分位的方法小结【5种方式】
2016/12/11 Javascript
jquery——九宫格大转盘抽奖实例
2017/01/16 Javascript
微信小程序获取循环元素id以及wx.login登录操作
2017/08/17 Javascript
详解js几个绕不开的事件兼容写法
2017/08/30 Javascript
Vue 2.0学习笔记之Vue中的computed属性
2017/10/16 Javascript
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
2018/07/04 Javascript
js实现按钮开关单机下拉菜单效果
2018/11/22 Javascript
Vue函数式组件-你值得拥有
2019/05/09 Javascript
layUI实现列表查询功能
2019/07/27 Javascript
VUE项目中加载已保存的笔记实例方法
2019/09/14 Javascript
解决ant-design-vue中menu菜单无法默认展开的问题
2020/10/31 Javascript
python中WSGI是什么,Python应用WSGI详解
2017/11/24 Python
python向已存在的excel中新增表,不覆盖原数据的实例
2018/05/02 Python
numpy.ndarray 交换多维数组(矩阵)的行/列方法
2018/08/02 Python
Python函数中参数是传递值还是引用详解
2019/07/02 Python
HTML的form表单和django的form表单
2019/07/25 Python
详解在Python中以绝对路径或者相对路径导入文件的方法
2019/08/30 Python
学校后勤人员职责
2013/12/27 职场文书
英文商务邀请信
2014/01/22 职场文书
入党介绍人评语
2014/05/06 职场文书
公务员试用期满考核材料
2014/05/22 职场文书
与美同行演讲稿
2014/09/13 职场文书
超市工作总结范文2014
2014/12/19 职场文书
2015年销售工作总结范文
2015/03/30 职场文书