自动生成文章摘要的代码[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下将多个数组合并成一个数组的方法与实例代码
Feb 03 PHP
深入分析php中接口与抽象类的区别
Jun 08 PHP
php中OR与|| AND与&amp;&amp;的区别总结
Oct 26 PHP
PHP学习笔记(一) 简单了解PHP
Aug 04 PHP
thinkphp缓存技术详解
Dec 09 PHP
php打印一个边长为N的实心和空心菱型的方法
Mar 02 PHP
php根据生日计算年龄的方法
Jul 13 PHP
PHP中的随机性 你觉得自己幸运吗?
Jan 22 PHP
PHP使用Mysqli类库实现完美分页效果的方法
Apr 07 PHP
thinkphp,onethink和thinkox中验证码不显示的解决方法分析
Jun 06 PHP
利用 fsockopen() 函数开放端口扫描器的实例
Aug 19 PHP
PHP的微信支付接口使用方法讲解
Mar 08 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使用递归函数实现数字累加的方法
2015/03/16 PHP
PHP中for循环与foreach的区别
2017/03/06 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
2020/02/27 PHP
javascript之dhDataGrid Ver2.0.0代码
2007/07/01 Javascript
IE 缓存策略的BUG的解决方法
2007/07/21 Javascript
Prototype 学习 工具函数学习($方法)
2009/07/12 Javascript
文本框根据输入内容自适应高度的代码
2011/10/24 Javascript
教你如何使用firebug调试功能了解javascript闭包和this
2015/03/04 Javascript
javascript的document中的动态添加标签实现方法
2016/10/24 Javascript
值得分享的Bootstrap Table使用教程
2016/11/23 Javascript
微信小程序 解决swiper不显示图片的方法
2017/01/04 Javascript
Bootstrap中data-target 到底是什么
2017/02/14 Javascript
JS计算距当前时间的时间差实例
2017/12/29 Javascript
nodejs 简单实现动态html的方法
2018/05/12 NodeJs
使用 JavaScript 创建并下载文件(模拟点击)
2019/10/25 Javascript
JS如何寻找数组中心索引过程解析
2020/06/01 Javascript
使用Python对IP进行转换的一些操作技巧小结
2015/11/09 Python
深入理解python中的select模块
2017/04/23 Python
Python3最长回文子串算法示例
2019/03/04 Python
PyQt5实现简单数据标注工具
2019/03/18 Python
Python分支语句与循环语句应用实例分析
2019/05/07 Python
Python-Tkinter Text输入内容在界面显示的实例
2019/07/12 Python
Python 利用高德地图api实现经纬度与地址的批量转换
2019/08/14 Python
Python with标签使用方法解析
2020/01/17 Python
Python 实现向word(docx)中输出
2020/02/13 Python
基于python图书馆管理系统设计实例详解
2020/08/05 Python
Expected conditions模块使用方法汇总代码解析
2020/08/13 Python
瑞典最好的运动鞋专卖店:Sneakersnstuff
2016/08/29 全球购物
幼师自荐信范文
2013/10/06 职场文书
幼儿园家长评语
2014/02/10 职场文书
保护环境建议书300字
2014/05/13 职场文书
股权转让协议范本
2014/12/07 职场文书
恋恋笔记本观后感
2015/06/16 职场文书
员工工作心得体会
2019/05/07 职场文书
北京大学中文系教授推荐的10本小说
2019/08/08 职场文书
Nginx动静分离配置实现与说明
2022/04/07 Servers