自动生成文章摘要的代码[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
一个简洁的多级别论坛
Oct 09 PHP
PHP文章按日期(月日)SQL归档语句
Nov 29 PHP
解析使用substr截取UTF-8中文字符串出现乱码的问题
Jun 20 PHP
PHP安全的URL字符串base64编码和解码
Jun 19 PHP
PHP5.3与5.5废弃与过期函数整理汇总
Jul 10 PHP
Yii2实现同时搜索多个字段的方法
Aug 10 PHP
php实现统计二进制中1的个数算法示例
Jan 23 PHP
php记录搜索引擎爬行记录的实现代码
Mar 02 PHP
php实现微信企业转账功能
Oct 02 PHP
掌握PHP垃圾回收机制详解
Mar 13 PHP
Laravel 5+ .env环境配置文件详解
Apr 06 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中关于抽象(abstract)类和抽象方法的问题分析
2014/01/03 PHP
个人写的PHP验证码生成类分享
2014/08/21 PHP
Joomla简单判断用户是否登录的方法
2016/05/04 PHP
PHP入门教程之数组用法汇总(创建,删除,遍历,排序等)
2016/09/11 PHP
php微信开发之百度天气预报
2016/11/18 PHP
JavaScript 注册事件代码
2011/01/27 Javascript
基于jquery实现状态限定编辑的代码
2012/02/11 Javascript
JavaScript 基础篇之对象、数组使用介绍(三)
2012/04/07 Javascript
在表单提交前进行验证的几种方式整理
2013/07/31 Javascript
javascript相关事件的几个概念
2015/05/21 Javascript
纯css实现窗户玻璃雨滴逼真效果
2015/08/23 Javascript
关于JS中prototype的理解
2015/09/07 Javascript
很实用的js选项卡切换效果
2016/08/12 Javascript
浅谈Javascript中的函数、this以及原型
2016/10/09 Javascript
JavaScript实现图片懒加载(Lazyload)
2016/11/28 Javascript
基于Bootstrap 3 JQuery及RegExp的表单验证功能
2017/02/16 Javascript
Express + Session 实现登录验证功能
2017/09/08 Javascript
详解JavaScript中的数组合并方法和对象合并方法
2018/05/11 Javascript
微信小程序当前时间时段选择器插件使用方法详解
2018/12/28 Javascript
在vue中使用setInterval的方法示例
2019/04/16 Javascript
通过微信公众平台获取公众号文章的方法示例
2019/12/25 Javascript
vue2路由方式--嵌套路由实现方法分析
2020/03/06 Javascript
[02:48]DOTA2超级联赛专访海涛:你们的选择没有错
2013/06/07 DOTA
[01:52]2014DOTA2西雅图邀请赛 V社开大会你不知道的小秘密
2014/07/08 DOTA
[03:58]兄弟们,回来开黑了!DOTA2昔日战友招募宣传视频
2016/07/17 DOTA
Python中shutil模块的常用文件操作函数用法示例
2016/07/05 Python
python实现获取Ip归属地等信息
2016/08/27 Python
使用TensorFlow实现二分类的方法示例
2019/02/05 Python
解决python对齐错误的方法
2020/07/16 Python
英国曼彻斯特宠物用品品牌:Bunty Pet Products
2019/07/27 全球购物
美国小蜜蜂Burt’s Bees德国官网:天然唇部、皮肤和身体护理产品
2020/06/14 全球购物
生产厂长岗位职责
2014/02/21 职场文书
2015年度销售个人工作总结
2015/03/31 职场文书
2019公司管理制度
2019/04/19 职场文书
关于golang高并发的实现与注意事项说明
2021/05/08 Golang
解决使用了nginx获取IP地址都是127.0.0.1 的问题
2021/09/25 Servers