自动生成文章摘要的代码[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 相关文章推荐
输出控制类
Oct 09 PHP
目录,文件操作详谈―PHP
Nov 25 PHP
用PHP实现图象锐化代码
Jun 14 PHP
php 处理上百万条的数据库如何提高处理查询速度
Feb 08 PHP
在Windows下编译适用于PHP 5.2.12及5.2.13的eAccelerator.dll(附下载)
May 04 PHP
PHP中SimpleXML函数用法分析
Nov 26 PHP
PHP答题类应用接口实例
Feb 09 PHP
详解php比较操作符的安全问题
Dec 03 PHP
Zend Framework入门知识点小结
Mar 19 PHP
yii2局部关闭(开启)csrf的验证的实例代码
Jul 10 PHP
为Plesk PHP7启用Oracle OCI8扩展方法总结
Mar 29 PHP
浅谈php调用python文件
Mar 29 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 强制下载文件代码
2010/10/24 PHP
基于PHP常用函数的用法详解
2013/05/10 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
2014/07/25 PHP
mouse_on_title.js
2006/08/25 Javascript
基于jQuery的模仿新浪微博时间的组件
2011/10/04 Javascript
Array.prototype.concat不是通用方法反驳[译]
2012/09/20 Javascript
深入理解JavaScript系列(25):设计模式之单例模式详解
2015/03/03 Javascript
Redis基本知识、安装、部署、配置笔记
2015/03/05 Javascript
JS中JSON对象和String之间的互转及处理技巧
2016/04/06 Javascript
JS代码随机生成姓名、手机号、身份证号、银行卡号
2016/04/27 Javascript
Javascript类型系统之undefined和null浅析
2016/07/13 Javascript
jquery+css3问卷答题卡翻页动画效果示例
2016/10/26 Javascript
jQuey将序列化对象在前台显示地实现代码(方法总结)
2016/12/13 Javascript
详解angular用$sce服务来过滤HTML标签
2017/04/11 Javascript
Angular中响应式表单的三种更新值方法详析
2017/08/22 Javascript
jQuery实现注册会员时密码强度提示信息功能示例
2017/09/05 jQuery
vue实现按需加载组件及异步组件功能
2019/05/27 Javascript
Vue基础学习之项目整合及优化
2019/06/02 Javascript
python启动办公软件进程(word、excel、ppt、以及wps的et、wps、wpp)
2009/04/09 Python
tensorflow实现KNN识别MNIST
2018/03/12 Python
Python高级特性切片(Slice)操作详解
2018/09/27 Python
对Python通过pypyodbc访问Access数据库的方法详解
2018/10/27 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
Python实现html转换为pdf报告(生成pdf报告)功能示例
2019/05/04 Python
python tkinter实现彩球碰撞屏保
2019/07/30 Python
使用python获取邮箱邮件的设置方法
2019/09/20 Python
python GUI库图形界面开发之PyQt5切换按钮控件QPushButton详细使用方法与实例
2020/02/28 Python
css3实现顶部社会化分享按钮示例
2014/05/06 HTML / CSS
微软台湾官方网站:Microsoft台湾
2018/08/15 全球购物
Fossil德国官网:化石手表、手袋、珠宝及配件
2019/12/07 全球购物
英国第一职业高尔夫商店:Clickgolf.co.uk
2020/11/18 全球购物
如何整合JQuery和Prototype
2014/01/31 面试题
募捐倡议书
2014/04/14 职场文书
爱国主义教育演讲稿
2014/08/26 职场文书
实习介绍信范文
2015/05/05 职场文书
领导欢送会主持词
2015/07/06 职场文书