自动生成文章摘要的代码[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模块 Memcached功能多于Memcache
Jun 14 PHP
ThinkPHP CURD方法之field方法详解
Jun 18 PHP
php格式化时间戳显示友好的时间实现思路及代码
Oct 23 PHP
基于GD2图形库的PHP生成图片缩略图类代码分享
Feb 08 PHP
PHP实现全角字符转为半角方法汇总
Jul 09 PHP
Yii2框架使用计划任务的方法
May 25 PHP
PHP线程的内存回收问题
Jul 08 PHP
PHP简单预防sql注入的方法
Sep 27 PHP
php中序列化与反序列化详解
Feb 13 PHP
Laravel中批量赋值Mass-Assignment的真正含义详解
Sep 29 PHP
PHP addslashes()函数讲解
Feb 03 PHP
laravel 解决后端无法获取到前端Post过来的值问题
Oct 22 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应用程序的七个习惯深入分析
2013/06/08 PHP
微信开发之网页授权获取用户信息(二)
2016/01/08 PHP
PHP微信支付开发实例
2016/06/22 PHP
php抽象方法和抽象类实例分析
2016/12/07 PHP
PHP获取ttf格式文件字体名的方法示例
2019/03/06 PHP
正则表达式判断是否存在中文和全角字符和判断包含中文字符串长度
2008/09/27 Javascript
使用Json比用string返回数据更友好,也更面向对象一些
2011/09/13 Javascript
JQuery1.6 使用方法三
2011/11/23 Javascript
Jquery读取URL参数小例子
2013/08/30 Javascript
js 定时器setTimeout无法调用局部变量的解决办法
2013/11/28 Javascript
使用insertAfter()方法在现有元素后添加一个新元素
2014/05/28 Javascript
JavaScript实现文字跟随鼠标特效
2015/08/06 Javascript
javascript数组去重的六种方法汇总
2015/08/16 Javascript
分享自己用JS做的扫雷小游戏
2016/02/17 Javascript
vue数字类型过滤器的示例代码
2017/09/07 Javascript
Egg.js 中 AJax 上传文件获取参数的方法
2018/10/10 Javascript
javascript实现京东登录显示隐藏密码
2020/08/02 Javascript
跟老齐学Python之画圈还不简单吗?
2014/09/20 Python
python UNIX_TIMESTAMP时间处理方法分析
2016/04/18 Python
Python获取SQLite查询结果表列名的方法
2017/06/21 Python
tensorflow之获取tensor的shape作为max_pool的ksize实例
2020/01/04 Python
python使用openpyxl操作excel的方法步骤
2020/05/28 Python
施华洛世奇韩国官网:SWAROVSKI韩国
2018/06/05 全球购物
Muziker英国:中欧最大的音乐家商店
2020/02/05 全球购物
英国时尚和家居用品零售商:Matalan
2021/02/28 全球购物
OSPF有什么优点?为什么OSPF比RIP收敛快?
2013/02/13 面试题
毕业自我鉴定
2013/11/05 职场文书
办公室秘书自我鉴定
2014/01/18 职场文书
医院总经理岗位职责
2014/02/04 职场文书
我为自己代言广告词
2014/03/18 职场文书
创先争优个人承诺书
2014/08/30 职场文书
社区活动总结范文
2015/05/07 职场文书
Python实现生成bmp图像的方法
2021/06/13 Python
手把手教你导入Go语言第三方库
2021/08/04 Golang
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript