自动生成文章摘要的代码[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 socket方式提交的post详解
Jul 19 PHP
PHP面向对象法则
Feb 23 PHP
浅谈PHP与C#的值类型指向区别的详解
May 21 PHP
php mb_substr()函数截取中文字符串应用示例
Jul 29 PHP
PHP中几个可以提高运行效率的代码写法、技巧分享
Aug 21 PHP
php上传功能集后缀名判断和随机命名(强力推荐)
Sep 10 PHP
PHP用FTP类上传文件视频等的简单实现方法
Sep 23 PHP
Laravel 5.1 on SAE环境开发教程【附项目demo源码】
Oct 09 PHP
Laravel框架实现model层的增删改查(CURD)操作示例
May 12 PHP
phpinfo无法显示的原因及解决办法
Feb 15 PHP
php数组指针函数功能及用法示例
Feb 11 PHP
PHP dirname(__FILE__)原理及用法解析
Oct 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
如何删除多级目录
2006/10/09 PHP
PHP操作文件类的函数代码(文件和文件夹创建,复制,移动和删除)
2011/11/10 PHP
PHP封装的验证码工具类定义与用法示例
2018/08/22 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
window.navigate 与 window.location.href 的使用区别介绍
2013/09/21 Javascript
判断JS对象是否拥有某种属性的两种方式
2013/12/02 Javascript
Jquery创建一个层当鼠标移动到层上面不消失效果
2013/12/12 Javascript
ExtJS中设置下拉列表框不可编辑的方法
2014/05/07 Javascript
JS自动倒计时30秒后按钮才可用(两种场景)
2015/08/31 Javascript
基于Node.js的JavaScript项目构建工具gulp的使用教程
2016/05/20 Javascript
Web程序员必备的7个JavaScript函数
2016/06/14 Javascript
原生JS轮播图插件
2017/02/09 Javascript
jquery 仿锚点跳转到页面指定位置的实例
2017/02/14 Javascript
100行代码理解和分析vue2.0响应式架构
2017/03/09 Javascript
自定义类似于jQuery UI Selectable 的Vue指令v-selectable
2017/08/23 jQuery
two.js之实现动画效果示例
2017/11/06 Javascript
vue2.0 实现页面导航提示引导的方法
2018/03/13 Javascript
我要点爆”微信小程序云开发之项目建立与我的页面功能实现
2019/05/26 Javascript
微信小程序用canvas画图并分享
2020/03/09 Javascript
three.js 实现露珠滴落动画效果的示例代码
2021/03/01 Javascript
Python 列表(List)操作方法详解
2014/03/11 Python
Python3遍历目录树实现方法
2015/05/22 Python
深入浅析Python字符编码
2015/11/12 Python
Python中Class类用法实例分析
2015/11/12 Python
PYTHON 中使用 GLOBAL引发的一系列问题
2016/10/12 Python
Python面向对象类的继承实例详解
2018/06/27 Python
Pyinstaller 打包发布经验总结
2020/06/02 Python
Html5页面二次分享的实现
2018/07/30 HTML / CSS
复古服装:RetroStage
2019/05/10 全球购物
美国新娘礼品店:The Paisley Box
2020/09/08 全球购物
《蒲公英》教学反思
2014/02/28 职场文书
新闻专业毕业生求职信
2014/08/08 职场文书
2014年团员学习十八大思想汇报
2014/09/13 职场文书
党员评议自我评价
2015/03/03 职场文书
教师专业技术工作总结2015
2015/05/13 职场文书
python turtle绘图命令及案例
2021/11/23 Python