请选择 进入手机版 | 继续访问电脑版
收藏本站腾讯微博新浪微博
点点网模板设计大赛 phpchina

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 用悬赏 三天解决问题 解决访问速度慢 论坛支持农历生日 - 给官方提建议

论坛活动及任务 归纳网站最新活动 地图任务 邮件更新任务:保护帐号安全

积分换实物,来参加蓝色理想积分兑换吧! 联系招聘客服 蓝色理想帮你找工作! 万元奖励等你拿——点点网模板设计大赛

查看: 5708|回复: 8

[php] [原创] 自动生成文章摘要[PHP 版本] [复制链接]

dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-9-8 13:57:21 |显示全部楼层
原创作品,转载请注明出处

By dknt From bbs.blueidea.com


实现内容:截断一段含有HTML代码的文本,但是不会出现围堵标记没有封闭的问题。

说明:这是PHP版的,用于在服务器端使用,如果你需要一个客户端版的,请阅读
     自动生成文章摘要[JavaScript 版本]

我们在写BLOG这样的程序时经常需要显示文章前一部分的,但是又怕不恰当的截断破坏封闭标签以造成整个文档结构破坏,使用我的函数可以在要求不高的情况下解决这个问题。

大家应该考虑这个函数在服务端应用还是在客户端应用。因为我考虑这个函数可能运行起来比较费机器,所以安全性要求不高的情况下可以放在客户端上。

最好数据表中单独一个字段放这个摘要,这样相应的数据库查询也优化了。牺牲一点点空间换很多时间还是划算的。

再聊一下安全性问题,主要是内容安全性。如果客户端意图更改正常的摘要信息的话,一般都是BLOG的主人才有这个权力,那么他使得摘要和原文的一致性破坏就是他自己的事了。内容以外的安全性都可以在服务端解决。所以还是推荐在客户端使用本函数。

核心代码
  1. // PHP 4.3 or above needed
  2. define("BRIEF_LENGTH", 800);                //Word amount of the Briefing of an Article

  3. function Generate_Brief($text){
  4.         global $Briefing_Length;
  5.         if(strlen($text) <= BRIEF_LENGTH ) return $text;       
  6.         $Foremost = substr($text, 0, BRIEF_LENGTH);

  7.         $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";
  8.         $Single = "/BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT/i";       
  9.        
  10.         $Stack = array(); $posStack = array();
  11.         preg_match_all($re,$Foremost,$matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
  12.        
  13.         /*        [Child-matching Specification]:
  14.                
  15.                 $matches[$i][1] : A "/" charactor indicating whether current "<...>" Friction is Closing Part
  16.                 $matches[$i][2] : Element Name.
  17.                 $matches[$i][3] : Right > of a "<...>" Friction        */

  18.         for($i = 0 ; $i < count($matches); $i++){
  19.                 if($matches[$i][1][0] == ""){
  20.                         $Elem = $matches[$i][2][0];
  21.                         if(preg_match($Single,$Elem) && $matches[$i][3][0] !=""){
  22.                                 continue;
  23.                         }
  24.                         array_push($Stack, strtoupper($matches[$i][2][0]));
  25.                         array_push($posStack, $matches[$i][2][1]);                       
  26.                         if($matches[$i][3][0] =="") break;
  27.                 }else{
  28.                         $StackTop = $Stack[count($Stack)-1];
  29.                         $End = strtoupper($matches[$i][2][0]);
  30.                         if(strcasecmp($StackTop,$End)==0){
  31.                                 array_pop($Stack);
  32.                                 array_pop($posStack);
  33.                                 if($matches[$i][3][0] ==""){
  34.                                         $Foremost = $Foremost.">";
  35.                                 }
  36.                         }
  37.                 }               
  38.         }

  39.         $cutpos = array_shift($posStack) - 1;       
  40.         $Foremost = substr($Foremost,0,$cutpos);
  41.         return $Foremost;
  42. };
复制代码


欢迎大家找错误。谢谢。

[ 本帖最后由 dknt 于 2006-9-8 16:07 编辑 ]
已有 1 人评分威望 收起 理由
帅青蛙 + 1 原创内容

总评分: 威望 + 1   查看全部评分

- 回帖取义,发帖成仁... -
西部数码顶级域名注册商39元抢注!
dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-11-2 12:09:53 |显示全部楼层
最近应用了一下,发现上面的函数对多字节字符集支持得不好,因此重写了一下。

如果遇到问题,不妨试试下面的函数。

  1. function Generate_Brief($text){
  2.         global $Briefing_Length;
  3.         mb_regex_encoding("UTF-8");
  4.         if(mb_strlen($text) <= BRIEF_LENGTH ) return $text;       
  5.         $Foremost = mb_substr($text, 0, BRIEF_LENGTH);

  6.         $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)[^>]*(>?)";
  7.         $Single = "/BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT|BR/i";       
  8.        
  9.         $Stack = array(); $posStack = array();
  10.        
  11.         mb_ereg_search_init($Foremost, $re, 'i');
  12.        
  13.         while($pos = mb_ereg_search_pos()){
  14.                 $match = mb_ereg_search_getregs();
  15.                 /*        [Child-matching Formulation]:
  16.                
  17.                         $matche[1] : A "/" charactor indicating whether current "<...>" Friction is Closing Part
  18.                         $matche[2] : Element Name.
  19.                         $matche[3] : Right > of a "<...>" Friction       
  20.                 */

  21.                 if($match[1]==""){
  22.                         $Elem = $match[2];
  23.                         if(mb_eregi($Single, $Elem) && $match[3] !=""){
  24.                                 continue;
  25.                         }
  26.                         array_push($Stack, mb_strtoupper($Elem));
  27.                         array_push($posStack, $pos[0]);                       
  28.                 }else{
  29.                         $StackTop = $Stack[count($Stack)-1];
  30.                         $End = mb_strtoupper($match[2]);
  31.                         if(strcasecmp($StackTop,$End)==0){
  32.                                 array_pop($Stack);
  33.                                 array_pop($posStack);
  34.                                 if($match[3] ==""){
  35.                                         $Foremost = $Foremost.">";
  36.                                 }
  37.                         }
  38.                 }
  39.         }
  40.        
  41.         $cutpos = array_shift($posStack) - 1;       
  42.         $Foremost =  mb_substr($Foremost,0,$cutpos,"UTF-8");
  43.         return $Foremost;
  44. };
复制代码
- 回帖取义,发帖成仁... -
租服务器,上51IDC | [长沙]招聘:PHP经理10K/WEB前端6K/PHP开发6K

使用道具 举报

xqsong 
帖子
160
体力
183
威望
0
发表于 2006-11-2 14:06:26 |显示全部楼层
老大
能作一个注释就对我等初学者来说更是棒了

使用道具 举报

Surran 
帖子
828
体力
1454
威望
2
居住地
福建省 福州市
发表于 2006-11-2 20:30:42 |显示全部楼层
如果服务器没有mb_string函数库支持呢?

使用道具 举报

dknt 楼主

详细数据读取中

银牌会员

帖子
884
体力
2959
威望
92
居住地
美洲 美国
发表于 2006-11-23 01:13:42 |显示全部楼层
没有mb_string函数库支持 ,我也不知道怎么办,我也是个菜鸟,要不就自己写一套吧。
- 回帖取义,发帖成仁... -

使用道具 举报

下弦月

初级会员 手机认证 

帖子
16
体力
136
威望
0
居住地
重庆市 九龙坡区
发表于 2011-12-8 16:14:38 |显示全部楼层
我都是用strip_tags()函数去除文章的标记之后再用substring()截取的

使用道具 举报

Wivien 
帖子
359
体力
263
威望
0
居住地
广东省 广州市
发表于 2011-12-9 17:56:45 |显示全部楼层
看起来挺不错的啊

使用道具 举报

帖子
52
体力
105
威望
0
发表于 2011-12-10 14:34:22 |显示全部楼层
我来看看 。。
http://www.sxtqw.com

使用道具 举报

帖子
84
体力
800
威望
0
居住地
广东省 广州市
发表于 2012-2-2 10:07:39 |显示全部楼层
好像也不错 。

我收藏了几个网上截取 自动闭合html标签的  http://www.diaoyude.cn/view_article_311.html
www.diaoyude.cn

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|安久科技提供CDN|blueidea.com ( 京ICP备05002321号 )  

GMT+8, 2012-2-13 13:04 , Processed in 0.172774 second(s), 9 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部