自动生成文章摘要的代码[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表单递交控件名称含有点号(.)会被转化为下划线(_)的处理方法
Jan 06 PHP
PHP根据两点间的经纬度计算距离
Oct 31 PHP
9个实用的PHP代码片段分享
Jan 22 PHP
php对文件进行hash运算的方法
Apr 03 PHP
php传值赋值和传地址赋值用法实例分析
Jun 20 PHP
PHP实现合并discuz用户
Aug 05 PHP
Symfony2实现在controller中获取url的方法
Mar 18 PHP
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
Sep 09 PHP
CakePHP框架Model关联对象用法分析
Aug 04 PHP
解决PHP curl或file_get_contents下载图片损坏或无法打开的问题
Oct 11 PHP
Laravel6.2中用于用户登录的新密码确认流程详解
Oct 16 PHP
Mac下关于PHP环境和扩展的安装详解
Oct 17 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
关于js与php互相传值的介绍
2013/06/25 PHP
PHP弱类型的安全问题详细总结
2016/09/25 PHP
ThinkPHP实现静态缓存和动态缓存示例代码
2017/05/02 PHP
基于JQuery框架的AJAX实例代码
2009/11/03 Javascript
JavaScript中的集合及效率
2010/01/08 Javascript
web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
2013/01/09 Javascript
7款风格新颖的jQuery/CSS3菜单导航分享
2013/04/23 Javascript
node.js中的fs.writeSync方法使用说明
2014/12/15 Javascript
javascript实现简单加载随机色方块
2015/12/25 Javascript
jquery设置表单元素为不可用的简单代码
2016/07/04 Javascript
jQuery弹出div层过2秒自动消失
2016/11/29 Javascript
一种angular的方法级的缓存注解(装饰器)
2018/03/13 Javascript
自定义javascript验证框架示例【附源码下载】
2019/05/31 Javascript
微信小程序实现音乐播放器
2019/11/20 Javascript
[03:07]完美世界DOTA2联赛PWL DAY10 决赛集锦
2020/11/11 DOTA
[32:07]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第一场 12.16
2020/12/17 DOTA
Python中对列表排序实例
2015/01/04 Python
python常规方法实现数组的全排列
2015/03/17 Python
使用Python的Scrapy框架编写web爬虫的简单示例
2015/04/17 Python
详解在Python程序中解析并修改XML内容的方法
2015/11/16 Python
浅析Python 中整型对象存储的位置
2016/05/16 Python
Python中pygal绘制雷达图代码分享
2017/12/07 Python
python类的方法属性与方法属性的动态绑定代码详解
2017/12/27 Python
Python读取csv文件分隔符设置方法
2019/01/14 Python
keras读取h5文件load_weights、load代码操作
2020/06/12 Python
如何在Python3中使用telnetlib模块连接网络设备
2020/09/21 Python
科颜氏加拿大官方网站: Kiehl’s加拿大
2016/08/16 全球购物
在家更换处方镜片:Lensabl
2019/05/01 全球购物
印尼购物网站:iLOTTE
2019/10/16 全球购物
教育系毕业生中文求职信范文
2013/10/06 职场文书
大学生文员专业个人求职信范文
2014/01/05 职场文书
餐饮采购员岗位职责
2014/03/15 职场文书
课外小组活动总结
2014/08/27 职场文书
奥巴马上海演讲稿
2014/09/10 职场文书
高中班主任心得体会
2016/01/07 职场文书
2016年第二十五次全国助残日活动总结
2016/04/01 职场文书