html截取 標簽自動補全

吃水不忘挖井人:http://www.jb51.net/article/51242.htm

/*
* ============================== 截取含有 html標簽的字符串 =========================
* @param (string) $str   待截取字符串
* @param (int)  $lenth  截取長度
* @param (string) $repalce 超出的內(nèi)容用$repalce替換之(該參數(shù)可以為帶有html標簽的字符串)
* @param (string) $anchor 截取錨點恰响,如果截取過程中遇到這個標記錨點就截至該錨點處
* @return (string) $result 返回值
* @demo  $res = cut_html_str($str, 256, '...'); //截取256個長度呢袱,其余部分用'...'替換
* -------------------------------------------------------------------------------
* $ Author: Wang Jian.  |   Email: wj@yurendu.com   |   Date: 2014/03/16
* ===============================================================================
*/
function cut_html_str($str, $lenth, $replace='', $anchor='<!-- break -->'){ 
    $_lenth = mb_strlen($str, "utf-8"); // 統(tǒng)計字符串長度(中溅呢、英文都算一個字符)
    if($_lenth <= $lenth){
        return $str;    // 傳入的字符串長度小于截取長度,原樣返回
    }
    $strlen_var = strlen($str);     // 統(tǒng)計字符串長度(UTF8編碼下-中文算3個字符烙常,英文算一個字符)
    if(strpos($str, '<') === false){ 
        return mb_substr($str, 0, $lenth);  // 不包含 html 標簽 亮靴,直接截取
    } 
    if($e = strpos($str, $anchor)){ 
        return mb_substr($str, 0, $e);  // 包含截斷標志宴树,優(yōu)先
    } 
    $html_tag = 0;  // html 代碼標記 
    $result = '';   // 摘要字符串
    $html_array = array('left' => array(), 'right' => array()); //記錄截取后字符串內(nèi)出現(xiàn)的 html 標簽藐握,開始=>left,結束=>right
    /*
    * 如字符串為:<h3><p><b>a</b></h3>,假設p未閉合褥芒,數(shù)組則為:array('left'=>array('h3','p','b'), 'right'=>'b','h3');
    * 僅補全 html 標簽嚼松,<? <% 等其它語言標記,會產(chǎn)生不可預知結果
    */
    for($i = 0; $i < $strlen_var; ++$i) { 
        if(!$lenth) break;  // 遍歷完之后跳出
        $current_var = substr($str, $i, 1); // 當前字符
        if($current_var == '<'){ // html 代碼開始 
            $html_tag = 1; 
            $html_array_str = ''; 
        }else if($html_tag == 1){ // 一段 html 代碼結束 
            if($current_var == '>'){ 
                $html_array_str = trim($html_array_str); //去除首尾空格锰扶,如 <br / > < img src="" / > 等可能出現(xiàn)首尾空格
                if(substr($html_array_str, -1) != '/'){ //判斷最后一個字符是否為 /献酗,若是,則標簽已閉合坷牛,不記錄
                    // 判斷第一個字符是否 /凌摄,若是,則放在 right 單元 
                    $f = substr($html_array_str, 0, 1); 
                    if($f == '/'){ 
                        $html_array['right'][] = str_replace('/', '', $html_array_str); // 去掉 '/' 
                    }else if($f != '?'){ // 若是?漓帅,則為 PHP 代碼,跳過
                        // 若有半角空格痴怨,以空格分割忙干,第一個單元為 html 標簽。如:<h2 class="a"> <p class="a"> 
                        if(strpos($html_array_str, ' ') !== false){ 
                        // 分割成2個單元浪藻,可能有多個空格捐迫,如:<h2 class="" id=""> 
                        $html_array['left'][] = strtolower(current(explode(' ', $html_array_str, 2))); 
                        }else{ 
                        //若沒有空格,整個字符串為 html 標簽爱葵,如:<b> <p> 等施戴,統(tǒng)一轉(zhuǎn)換為小寫
                        $html_array['left'][] = strtolower($html_array_str); 
                        } 
                    } 
                } 
                $html_array_str = ''; // 字符串重置
                $html_tag = 0; 
            }else{ 
                $html_array_str .= $current_var; //將< >之間的字符組成一個字符串,用于提取 html 標簽
            } 
        }else{ 
            --$lenth; // 非 html 代碼才記數(shù)
        } 
        $ord_var_c = ord($str{$i}); 
        switch (true) { 
            case (($ord_var_c & 0xE0) == 0xC0): // 2 字節(jié) 
                $result .= substr($str, $i, 2); 
                $i += 1; break; 
            case (($ord_var_c & 0xF0) == 0xE0): // 3 字節(jié)
                $result .= substr($str, $i, 3); 
                $i += 2; break; 
            case (($ord_var_c & 0xF8) == 0xF0): // 4 字節(jié)
                $result .= substr($str, $i, 4); 
                $i += 3; break; 
            case (($ord_var_c & 0xFC) == 0xF8): // 5 字節(jié) 
                $result .= substr($str, $i, 5); 
                $i += 4; break; 
            case (($ord_var_c & 0xFE) == 0xFC): // 6 字節(jié)
                $result .= substr($str, $i, 6); 
                $i += 5; break; 
            default: // 1 字節(jié) 
                $result .= $current_var; 
        } 
    } 
    if($html_array['left']){ //比對左右 html 標簽,不足則補全
        $html_array['left'] = array_reverse($html_array['left']); //翻轉(zhuǎn)left數(shù)組萌丈,補充的順序應與 html 出現(xiàn)的順序相反
        foreach($html_array['left'] as $index => $tag){ 
            $key = array_search($tag, $html_array['right']); // 判斷該標簽是否出現(xiàn)在 right 中
            if($key !== false){ // 出現(xiàn)赞哗,從 right 中刪除該單元
                unset($html_array['right'][$key]); 
            }else{ // 沒有出現(xiàn),需要補全 
                $result .= '</'.$tag.'>'; 
            } 
        } 
    } 
    return $result.$replace; 
}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辆雾,一起剝皮案震驚了整個濱河市肪笋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌度迂,老刑警劉巖藤乙,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惭墓,居然都是意外死亡坛梁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門腊凶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來划咐,“玉大人拴念,你說我怎么就攤上這事〖庋辏” “怎么了丈莺?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長送丰。 經(jīng)常有香客問我缔俄,道長,這世上最難降的妖魔是什么器躏? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任俐载,我火速辦了婚禮,結果婚禮上登失,老公的妹妹穿的比我還像新娘遏佣。我一直安慰自己,他們只是感情好揽浙,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布状婶。 她就那樣靜靜地躺著,像睡著了一般馅巷。 火紅的嫁衣襯著肌膚如雪膛虫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天钓猬,我揣著相機與錄音稍刀,去河邊找鬼。 笑死敞曹,一個胖子當著我的面吹牛账月,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播澳迫,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼局齿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了纲刀?” 一聲冷哼從身側(cè)響起项炼,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎示绊,沒想到半個月后锭部,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡面褐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年拌禾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片展哭。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡湃窍,死狀恐怖闻蛀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情您市,我是刑警寧澤觉痛,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站茵休,受9級特大地震影響薪棒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜榕莺,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一俐芯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钉鸯,春花似錦吧史、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至岩睁,卻和暖如春莽使,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笙僚。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留灵再,地道東北人肋层。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像翎迁,于是被迫代替她去往敵國和親栋猖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容