自动生成文章摘要的代码[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下过滤HTML代码的函数
Dec 10 PHP
php采集速度探究总结(原创)
Apr 18 PHP
PHP 字符串加密函数(在指定时间内加密还原字符串,超时无法还原)
Apr 28 PHP
由php的call_user_func传reference引发的思考
Jul 23 PHP
php 获取全局变量的代码
Apr 21 PHP
PHP学习笔记 IIS7下安装配置php环境
Oct 29 PHP
解析crontab php自动运行的方法
Jun 24 PHP
ThinkPHP中自定义错误页面和提示页面实例
Nov 22 PHP
php简单日历函数
Oct 28 PHP
php微信开发接入
Aug 27 PHP
laravel 之 Eloquent 模型修改器和序列化示例
Oct 17 PHP
PHP实现计算器小功能
Aug 28 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
解决中英文字符串长度问题函数
2007/01/16 PHP
php的SimpleXML方法读写XML接口文件实例解析
2014/06/16 PHP
CI框架中zip类应用示例
2014/06/17 PHP
PHP 范围解析操作符(::)用法分析【访问静态成员和类常量】
2020/04/14 PHP
为javascript添加String.Format方法
2020/08/11 Javascript
jquery DIV撑大让滚动条滚到最底部代码
2013/06/06 Javascript
JS+CSS实现DIV层的展开、收缩效果
2016/01/28 Javascript
JavaScript知识点总结(五)之Javascript中两个等于号(==)和三个等于号(===)的区别
2016/05/31 Javascript
vue实现列表的添加点击
2016/12/29 Javascript
jQuery实现文档树效果
2017/02/20 Javascript
Javascript仿京东放大镜的效果
2017/03/01 Javascript
微信小程序实现传参数的几种方法示例
2018/01/10 Javascript
使用vue制作探探滑动堆叠组件的实例代码
2018/03/07 Javascript
webuploader分片上传的实现代码(前后端分离)
2018/09/10 Javascript
Puppeteer 爬取动态生成的网页实战
2018/11/14 Javascript
[59:00]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第一场 3月7日
2021/03/11 DOTA
Python的Django中django-userena组件的简单使用教程
2015/05/30 Python
[原创]教女朋友学Python(一)运行环境搭建
2017/11/29 Python
Python字典操作详细介绍及字典内建方法分享
2018/01/04 Python
python测试mysql写入性能完整实例
2018/01/18 Python
快速了解python leveldb
2018/01/18 Python
pandas将numpy数组写入到csv的实例
2018/07/04 Python
Flask实现图片的上传、下载及展示示例代码
2018/08/03 Python
解决python中0x80072ee2错误的方法
2020/07/19 Python
日本最大的眼镜购物网站:Oh My Glasses
2016/11/13 全球购物
Clarks英国官方网站:全球领军鞋履品牌
2016/11/26 全球购物
中软国际Java程序员机试题
2012/08/19 面试题
销售文员岗位职责
2013/11/29 职场文书
大学生冰淇淋店商业计划书
2014/01/14 职场文书
小学运动会表扬稿
2014/01/19 职场文书
实习会计求职自荐信范文
2014/03/10 职场文书
公司领导班子召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
关于感谢信的范文
2015/01/23 职场文书
公司的力量观后感
2015/06/05 职场文书
公司宣传语大全
2015/07/13 职场文书
关于五一放假的通知
2015/08/18 职场文书