since.2006  

做文章系统首页时经常需要截断文章,只显示文章一部分摘要内容,这样将不会导致文章过多时使首页看起来过于臃肿。

截断含html标签的文章内容时会碰到一些问题,比如截取的地方正好是img标签,这样就会使整个页面变形。

在网上找到一种解决方法http://www.hua2r.com/blog/20c3dfecb972ccb0421cd0402bfa1106.xml

本BLOG系统首页就是用这种思路来截取字符串的。

具体思路为:

  1. 用正则将html标签和文章内容分开
  2. html标签不参加字符串长度计算(如果碰到html标签,直接拼加,是真正内容时,才计算长度)
  3. 根据html标签进/出栈(Stack,先进后出)
  4. 循环第2步,3步
  5. 超过长度,跳出循环,如果栈中有html标记,将html标记补到内容后面

上面网址列出的代码片段有几个小问题,没有考虑到font标签的处理情况。下面贴出俺修改后的

function htmlSubString($content, $maxLength=300) {    
    $content = preg_split('/(<[^>]+?>)/i', $content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);    
    $outString = '';    
    $curLength = 0;    
    $tagStack = array();    
    foreach($content as $value) {    
        if(trim($value) == '') continue;    
        $outString .= $value;    
        if (preg_match('/^([^<>]+)$/i', $value)) {    
            $curLength += strlen($value);    
            if($maxLength < $curLength) break;    
        } else if(preg_match('/<IMG([^>]+)?>/i', $value) || preg_match('/<PARAM([^>]+)?>/i', $value) || preg_match('/<!([^>]+)?>/i', $value) || preg_match('/<HR([^>]+)?>/i', $value) || preg_match('/<BR([^>]+)?>/i', $value)) {    
            continue;    
        } else if(preg_match('/<\/([^>]+?)>/i', $value, $matches)) {    
            array_pop($tagStack);    
        } else if(preg_match('/<(\w*)\s*.*/i', $value, $matches)) {    
            array_push($tagStack, $matches[1]);    
        } else {    
            break;    
        }    
    }    
   
    $patchStack = array_reverse($tagStack);    
    foreach($patchStack as $tagName) {    
        $outString .= "</$TAGNAME>";    
    }    
    return $outString;    
}  
Posted by hee at 22:03 PM | Permalink | 评论(1)