php截取html字符串及自动补全html标签的方法


Posted in PHP onJanuary 15, 2015

本文实例讲述了php截取html字符串及自动补全html标签的方法。分享给大家供大家参考。具体分析如下:

这里总结一下关于利用php截取html字符串自动补全html标签,实际开发中会经常碰到,很多人直接先strip_tags过滤掉html标签,但是就只剩下纯文本了,可读性非常差,下面是一个函数,代码如下:

/** 

 * 截取HTML,并自动补全闭合 

 * @param $html 

 * @param $length 

 * @param $end 

 */ 

function subHtml($html,$length) { 

 $result = ''; 

 $tagStack = array(); 

 $len = 0; 

 

 $contents = preg_split("~(<[^>]+?>)~si",$html, -1,PREG_SPLIT_NO_EMPTY| PREG_SPLIT_DELIM_CAPTURE); 

 foreach($contents as $tag) 

 { 

 if (trim($tag)=="")  continue; 

 if(preg_match("~<([a-z0-9]+)[^/>]*?/>~si",$tag)){ 

 $result .= $tag; 

 }else if(preg_match("~</([a-z0-9]+)[^/>]*?>~si",$tag,$match)){ 

 if($tagStack[count($tagStack)-1] == $match[1]){ 

 array_pop($tagStack); 

 $result .= $tag; 

 } 

 }else if(preg_match("~<([a-z0-9]+)[^/>]*?>~si",$tag,$match)){ 

 array_push($tagStack,$match[1]); 

 $result .= $tag; 

 }else if(preg_match("~<!--.*?-->~si",$tag)){ 

 $result .= $tag; 

 }else{ 

 if($len + mstrlen($tag) < $length){ 

 $result .= $tag; 

 $len += mstrlen($tag);  

 }else { 

 $str = msubstr($tag,0,$length-$len+1); 

 $result .= $str; 

 break; 

 } 

 

 } 

 } 

 while(!emptyempty($tagStack)){ 

 $result .= '</'.array_pop($tagStack).'>'; 

 } 

 return  $result; 

} 

 

/** 

 * 截取中文字符串 

 * @param $string 字符串 

 * @param $start 起始位 

 * @param $length 长度 

 * @param $charset  编码 

 * @param $dot 附加字串 

 */ 

function msubstr($string, $start, $length,$dot='',$charset = 'UTF-8') { 

 $string = str_replace(array('&', '"', '<', '>',' '), array('&', '"', '<', '>',' '), $string); 

 if(strlen($string) <= $length) { 

 return $string; 

 } 

 

 if(strtolower($charset) == 'utf-8') { 

 $n = $tn = $noc = 0; 

 while($n < strlen($string)) { 

 $t = ord($string[$n]); 

 if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) { 

 $tn = 1; $n++; 

 } elseif(194 <= $t && $t <= 223) { 

 $tn = 2; $n += 2; 

 } elseif(224 <= $t && $t <= 239) { 

 $tn = 3; $n += 3; 

 } elseif(240 <= $t && $t <= 247) { 

 $tn = 4; $n += 4; 

 } elseif(248 <= $t && $t <= 251) { 

 $tn = 5; $n += 5; 

 } elseif($t == 252 || $t == 253) { 

 $tn = 6; $n += 6; 

 } else { 

 $n++; 

 } 

 $noc++; 

 if($noc >= $length) { 

 break; 

 } 

 } 

 if($noc > $length) { 

 $n -= $tn; 

 } 

 $strcut = substr($string, 0, $n); 

 } else { 

 for($i = 0; $i < $length; $i++) { 

 $strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i]; 

 } 

 } 

 

 return $strcut.$dot; 

} 

 

/** 

 * 取得字符串的长度,包括中英文。 

 */ 

function mstrlen($str,$charset = 'UTF-8'){ 

 if (function_exists('mb_substr')) { 

 $length=mb_strlen($str,$charset); 

 } elseif (function_exists('iconv_substr')) { 

 $length=iconv_strlen($str,$charset); 

 } else {

 preg_match_all("/[x01-x7f]|[xc2-xdf][x80-xbf]|xe0[xa0-xbf][x80-xbf]|[xe1-xef][x80-xbf][x80-xbf]|xf0[x90-xbf][x80-xbf][x80-xbf]|[xf1-xf7][x80-xbf][x80-xbf][x80-xbf]/", $text, $ar);   

 $length=count($ar[0]); 

 } 

 return $length; 

}

实例,代码如下:
* @param 要截取的HTML $str 

* @param 截取的数量 $num 

* @param 是否需要加上更多 $more 

* @return 截取串 

*/ 

function phpos_chsubstr_ahtml($str,$num,$more=false) 

{ 

    $leng=strlen($str); 

      if($num>=$leng)

      return $str; 

    $word=0; 

    $i=0;                        /** 字符串指针 **/ 

    $stag=array(array());        /** 存放开始HTML的标志 **/ 

    $etag=array(array());        /** 存放结束HTML的标志 **/ 

    $sp = 0; 

    $ep = 0; 

      while($word!=$num) 

      { 

          if(ord($str[$i])>128) 

          { 

            //$re.=substr($str,$i,3); 

            $i+=3; 

            $word++; 

          } 

          else if ($str[$i]=='<') 

          { 

              if ($str[$i+1] == '!') 

              { 

                $i++; 

                  continue; 

              } 

 

              if ($str[$i+1]=='/')     

              { 

                $ptag=&$etag ; 

                $k=&$ep; 

                $i+=2; 

              } 

              else                     

              { 

                $ptag=&$stag; 

                $i+=1; 

                $k=&$sp; 

              } 

 

              for(;$i<$leng;$i++)         

              { 

                  if ($str[$i] == ' ') 

                  { 

                    $ptag[$k] = implode('',$ptag[$k]); 

                    $k++; 

                      break; 

                  } 

                  if ($str[$i] != '>')  

                  { 

                    $ptag[$k][]=$str[$i]; 

                      continue; 

                  } 

                  else                 

                  { 

                    $ptag[$k] = implode('',$ptag[$k]); 

                    $k++; 

                      break; 

                  } 

              } 

            $i++; 

              continue; 

          } 

          else 

          { 

            //$re.=substr($str,$i,1); 

            $word++; 

            $i++; 

          } 

      } 

      foreach ($etag as $val) 

      { 

        $key1=array_search($val,$stag); 

          if ($key1 !== false)          unset($stag[$key]); 

      } 

      foreach ($stag as $key => $val) 

      { 

          if (in_array($val,array('br','img'))) unset($stag[$key1]); 

      } 

    array_reverse($stag); 

    $ends = '</'.implode('></',$stag).'>'; 

    $re = substr($str,0,$i).$ends; 

      if($more)    $re.='...'; 

      return $re; 

}

PHP截取字符串,生成文章摘要,我们在写BLOG时经常需要显示文章前一部分,但是又怕不恰当截断破坏封闭标签以造成整个文档结构破坏,代码如下:
function text_zhaiyao($text,$length){ //文章摘要生成函数  $test:内容 $length:摘要长度 

    global $Briefing_Length; 

    mb_regex_encoding("UTF-8"); 

    if(mb_strlen($text) <= $length ) return $text; 

    $Foremost = mb_substr($text, 0, $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; 

}

希望本文所述对大家的php程序设计有所帮助。

PHP 相关文章推荐
PHP自动更新新闻DIY
Oct 09 PHP
给php新手谈谈我的学习心得
Feb 25 PHP
PHP程序61条面向对象分析设计的经验小结
Nov 12 PHP
php中强制下载文件的代码(解决了IE下中文文件名乱码问题)
May 09 PHP
php图片上传存储源码并且可以预览
Aug 26 PHP
ThinkPHP 连接Oracle数据库的详细教程[全]
Jul 16 PHP
php适配器模式介绍
Aug 14 PHP
解析php中curl_multi的应用
Jul 17 PHP
ThinkPHP模板Switch标签用法示例
Jun 30 PHP
PHP中is_file()函数使用指南
May 08 PHP
PHP实现的最大正向匹配算法示例
Dec 19 PHP
linux mint下安装phpstorm2020包括JDK部分的教程详解
Sep 17 PHP
php在linux下检测mysql同步状态的方法
Jan 15 #PHP
php中静态类与静态变量用法的区别分析
Jan 15 #PHP
将FCKeditor导入PHP+SMARTY的实现方法
Jan 15 #PHP
php通过Chianz.com获取IP地址与地区的方法
Jan 14 #PHP
php中JSON的使用与转换
Jan 14 #PHP
php rsa加密解密使用详解
Jan 14 #PHP
ThinkPHP 404页面的设置方法
Jan 14 #PHP
You might like
php导出word文档与excel电子表格的简单示例代码
2014/03/08 PHP
swoole和websocket简单聊天室开发
2017/11/18 PHP
详解提高使用Java反射的效率方法
2019/04/29 PHP
php设计模式之享元模式分析【星际争霸游戏案例】
2020/03/23 PHP
动态表格Table类的实现
2009/08/26 Javascript
javascript检测浏览器flash版本的实现代码
2011/12/06 Javascript
jQuery控制输入框只能输入数值的小例子
2013/03/20 Javascript
javascript不同类型数据之间的运算的转换方法
2014/02/13 Javascript
jQuery源码分析之jQuery中的循环技巧详解
2014/09/06 Javascript
jQuery显示和隐藏 常用的状态判断方法
2015/01/29 Javascript
js实现简单div拖拽功能实例
2015/05/12 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
学习使用AngularJS文件上传控件
2016/02/16 Javascript
JavaScript中的事件委托及好处
2016/07/12 Javascript
js倒计时简单实现代码
2016/08/11 Javascript
js实现随机点名小功能
2017/08/17 Javascript
基于Node.js模板引擎教程-jade速学与实战1
2017/09/17 Javascript
JS实现按钮添加背景音乐示例代码
2017/10/17 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
解决JSON.stringify()自动将中文转译成unicode的问题
2018/01/05 Javascript
微信小程序icon组件使用详解
2018/01/31 Javascript
微信小程序实现图片上传功能
2018/05/28 Javascript
angular 数据绑定之[]和{{}}的区别
2018/09/25 Javascript
Vue实现穿梭框效果
2020/09/30 Javascript
解读Django框架中的低层次缓存API
2015/07/24 Python
Python切换pip安装源的方法详解
2016/11/18 Python
Python生成数字图片代码分享
2017/10/31 Python
pandas数据处理基础之筛选指定行或者指定列的数据
2018/05/03 Python
python字典嵌套字典的情况下找到某个key的value详解
2019/07/10 Python
澳大利亚最大的百货公司:Myer
2018/12/21 全球购物
为什么需要版本控制?
2013/08/08 面试题
前台领班岗位职责
2013/12/04 职场文书
珠宝店促销方案
2014/03/21 职场文书
2015年求职自荐信范文
2015/03/04 职场文书
2015年质量月活动总结报告
2015/03/27 职场文书
2016大学生入党积极分子心得体会
2016/01/06 职场文书