自动生成文章摘要的代码[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 SQL防注入代码集合
Apr 25 PHP
PHP Global变量定义当前页面的全局变量实现探讨
Jun 05 PHP
浅谈php扩展imagick
Jun 02 PHP
浅析ThinkPHP的模板输出功能
Jul 01 PHP
php微信公众开发之获取周边酒店信息的方法
Dec 22 PHP
百度工程师讲PHP函数的实现原理及性能分析(三)
May 13 PHP
在Mac上编译安装PHP7的开发环境
Jul 28 PHP
php使用Header函数,PHP_AUTH_PW和PHP_AUTH_USER做用户验证
May 04 PHP
php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
Nov 07 PHP
PHP简单获取上月、本月、近15天、近30天的方法示例
Jul 03 PHP
Laravel框架处理用户的请求操作详解
Dec 20 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中imagick函数的中文解释
2015/01/21 PHP
php获取'/'传参的值简单方法
2017/07/13 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
用js判断用户浏览器是否是XP SP2的IE6
2007/03/08 Javascript
javascript jQuery $.post $.ajax用法
2008/07/09 Javascript
Jquery 基础学习笔记
2009/05/29 Javascript
jquery nth-child()选择器的简单应用
2010/07/10 Javascript
flexigrid 类似ext grid的JS表格代码
2010/07/17 Javascript
使用jquery选择器如何获取父级元素、同级元素、子元素
2014/05/14 Javascript
jQuery实现鼠标经过提示信息的地图热点效果
2015/04/26 Javascript
jquery遍历函数siblings()用法实例
2015/12/24 Javascript
Markdown与Bootstrap相结合实现图片自适应属性
2016/05/04 Javascript
浅析jQuery 3.0中的Data
2016/06/14 Javascript
js 函数式编程学习笔记
2017/03/25 Javascript
微信小程序开发之toast等弹框提示使用教程
2017/06/08 Javascript
对angular 实时更新模板视图的方法$apply详解
2018/10/09 Javascript
Vue Element UI + OSS实现上传文件功能
2019/07/31 Javascript
详解elementui之el-image-viewer(图片查看器)
2019/08/30 Javascript
JS实现简单省市二级联动
2019/11/27 Javascript
Vuex实现数据共享的方法
2019/12/20 Javascript
js实现html滑动图片拼图验证
2020/06/24 Javascript
vue 如何使用递归组件
2020/10/23 Javascript
Python selenium的基本使用方法分析
2019/12/21 Python
python实现视频压缩功能
2020/12/18 Python
世界上最大的网络主机公司:1&1
2016/10/12 全球购物
俄罗斯厨房产品购物网站:COOK HOUSE
2021/03/15 全球购物
公司董事长职责
2013/12/12 职场文书
社区党总支书记先进事迹材料
2014/01/24 职场文书
科技工作者先进事迹
2014/08/16 职场文书
师范生免费教育协议书范本
2014/10/09 职场文书
财务人员个人工作总结
2015/02/27 职场文书
经费申请报告
2015/05/15 职场文书
网络妈妈观后感
2015/06/08 职场文书
Vue中foreach数组与js中遍历数组的写法说明
2021/06/05 Vue.js
nginx内存池源码解析
2021/11/20 Servers
golang生成并解析JSON
2022/04/14 Golang