自动生成文章摘要的代码[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中的内存管理问题
Aug 31 PHP
php中动态修改ini配置
Oct 14 PHP
smarty缓存用法分析
Dec 16 PHP
Yii中使用PHPExcel导出Excel的方法
Dec 26 PHP
学习php设计模式 php实现单例模式(singleton)
Dec 07 PHP
Thinkphp框架开发移动端接口(1)
Aug 18 PHP
PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)
Nov 15 PHP
PHP排序算法之冒泡排序(Bubble Sort)实现方法详解
Apr 20 PHP
php反射学习之依赖注入示例
Jun 14 PHP
PHP swoole和redis异步任务实现方法分析
Aug 12 PHP
laravel 实现设置时区的简单方法
Oct 10 PHP
Laravel5.1 框架数据库操作DB运行原生SQL的方法分析
Jan 07 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中创建并处理图象
2006/10/09 PHP
php中使用addslashes函数报错问题的解决方法
2013/02/06 PHP
解析PHP中DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用
2013/06/21 PHP
使用淘宝IP库获取用户ip地理位置
2013/10/27 PHP
ThinkPHP实现一键清除缓存方法
2014/06/26 PHP
Java中final关键字详解
2015/08/10 PHP
PHP封装的字符串加密解密函数
2015/12/18 PHP
一些javascript一些题目的解析
2010/12/25 Javascript
JQuery入门——事件切换之toggle()方法应用介绍
2013/02/05 Javascript
javascript拖拽上传类库DropzoneJS使用方法
2013/12/05 Javascript
轻松创建nodejs服务器(4):路由
2014/12/18 NodeJs
JavaScript 学习笔记之基础中的基础
2015/01/13 Javascript
javascript中的previousSibling和nextSibling的正确用法
2015/09/16 Javascript
js判断手机号运营商的方法
2015/10/23 Javascript
IntersectionObserver API 详解篇
2016/12/11 Javascript
移动端日期插件Mobiscroll.js使用详解
2016/12/19 Javascript
vue组件jsx语法的具体使用
2018/05/21 Javascript
vue实现todolist功能、todolist组件拆分及todolist的删除功能
2019/04/11 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
2020/12/04 Vue.js
详解Python中的内建函数,可迭代对象,迭代器
2019/04/29 Python
python conda操作方法
2019/09/11 Python
Python 线程池用法简单示例
2019/10/02 Python
在tensorflow中设置使用某一块GPU、多GPU、CPU的操作
2020/02/07 Python
Python 如何批量更新已安装的库
2020/05/26 Python
python中Pexpect的工作流程实例讲解
2021/03/02 Python
美国名表在线商城:Ashford(支持中文)
2019/09/24 全球购物
航空大学应届生求职信
2013/11/10 职场文书
《鞋匠的儿子》教学反思
2014/03/02 职场文书
五一手机促销方案
2014/03/08 职场文书
担保书怎么写
2014/04/01 职场文书
数学系毕业生求职信
2014/05/29 职场文书
居委会四风问题个人对照检查材料
2014/09/25 职场文书
党委书记群众路线对照检查材料思想汇报
2014/10/04 职场文书
运动会加油稿20字
2014/11/15 职场文书
Nginx配置80端口访问8080及项目名地址方法解析
2021/03/31 Servers
mysql中int(3)和int(10)的数值范围是否相同
2021/10/16 MySQL