自动生成文章摘要的代码[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写的serv-u的web申请账号的程序
Oct 09 PHP
使用字符串函数输出整数化的PHP版本号
Oct 09 PHP
php中常用字符串处理代码片段整理
Nov 07 PHP
PHP操作文件类的函数代码(文件和文件夹创建,复制,移动和删除)
Nov 10 PHP
PHP获取栏目的所有子级和孙级栏目的ID号示例
Apr 01 PHP
Thinkphp中import的几个用法详细介绍
Jul 02 PHP
wordpress安装过程中遇到中文乱码的处理方法
Apr 21 PHP
linux下php上传文件注意事项
Jun 11 PHP
thinkPHP+phpexcel实现excel报表输出功能示例
Jun 06 PHP
关于PHP虚拟主机概念及如何选择稳定的PHP虚拟主机
Nov 20 PHP
Yii框架通过请求组件处理get,post请求的方法分析
Sep 03 PHP
PHP+MySql实现一个简单的留言板
Jul 19 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利用REFERER根居访问来地址进行页面跳转
2013/09/28 PHP
正确的PHP匹配UTF-8中文的正则表达式
2015/05/13 PHP
阿里云的WindowsServer2016上部署php+apache
2018/07/17 PHP
在PHP中输出JS语句以及乱码问题的解决方案
2019/02/13 PHP
在Laravel5中正确设置文件权限的方法
2019/05/22 PHP
setTimeout与setInterval在不同浏览器下的差异
2010/01/24 Javascript
js判断字符长度以及中英文数字等
2013/12/31 Javascript
jquery 取子节点及当前节点属性值的方法
2014/08/24 Javascript
JavaScript使用concat连接数组的方法
2015/04/06 Javascript
javascript数组去重的方法汇总
2015/04/14 Javascript
jQuery图片渐变特效的简单实现
2016/06/25 Javascript
微信小程序中实现一对多发消息详解及实例代码
2017/02/14 Javascript
微信小程序 出现错误:{&quot;baseresponse&quot;:{&quot;errcode&quot;:-80002,&quot;errmsg&quot;:&quot;&quot;}}解决办法
2017/02/23 Javascript
快速解决brew安装特定版本flow的问题
2018/05/17 Javascript
纯异步nodejs文件夹(目录)复制功能
2019/09/03 NodeJs
JavaScript实现图片上传并预览并提交ajax
2019/09/30 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
2020/03/14 Javascript
vue组件开发之tab切换组件使用详解
2020/08/21 Javascript
[06:33]DOTA2亚洲邀请赛小组赛第二日 TOP10精彩集锦
2015/01/31 DOTA
Python import用法以及与from...import的区别
2015/05/28 Python
详谈套接字中SO_REUSEPORT和SO_REUSEADDR的区别
2018/04/28 Python
pandas数据筛选和csv操作的实现方法
2019/07/02 Python
python3实现弹弹球小游戏
2019/11/25 Python
python3.6连接mysql数据库及增删改查操作详解
2020/02/10 Python
keras读取训练好的模型参数并把参数赋值给其它模型详解
2020/06/15 Python
详解tf.device()指定tensorflow运行的GPU或CPU设备实现
2021/02/20 Python
python中使用asyncio实现异步IO实例分析
2021/02/26 Python
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
2018/12/29 HTML / CSS
CSS3 @media的基本用法总结
2019/09/10 HTML / CSS
如何开启linux的ssh服务
2013/06/03 面试题
AURALog面试题软件测试方面
2013/10/22 面试题
构造方法和其他方法的区别
2016/04/26 面试题
幼师自我鉴定范文
2013/10/01 职场文书
2016年教育局“我们的节日——端午节”主题活动总结
2016/04/01 职场文书
数据库的高级查询六:表连接查询:外连接(左外连接,右外连接,UNION关键字,连接中ON与WHERE的不同)
2021/04/05 MySQL
浅谈JS和Nodejs中的事件驱动
2021/05/05 NodeJs