當前位置: 首頁> 最新文章列表> 如何使用mb_strcut 函數截取HTML文本中的內容

如何使用mb_strcut 函數截取HTML文本中的內容

gitbox 2025-05-29

一、mb_strcut 的基礎用法

mb_strcut以字節為單位截取字符串,與mb_substr不同的是, mb_strcut是按字節截取,常用於處理多字節編碼。

示例:

 <?php
$str = "這是一個測試字符串";
echo mb_strcut($str, 0, 6, "UTF-8");  // 輸出:這是一個
?>

這裡的6 是字節數,中文字符在UTF-8 中一般佔3個字節,因此截取6字節等於截取2個漢字。

二、為何直接截取HTML 代碼會出錯?

假設有一段HTML 代碼:

 <?php
$html = "<p>這是一個<strong>測試</strong>字符串。</p>";

如果直接用mb_strcut截取,可能截斷在標籤中間:

 $cut = mb_strcut($html, 0, 15, "UTF-8");
echo $cut;

這可能輸出不完整的標籤,比如<p>這是一個<strong>測,導致瀏覽器渲染出錯。

三、解決方案思路

  1. 先把HTML 解析成純文本,用mb_strcut截取純文本內容。

  2. 根據截取後的文本長度,映射回原始HTML ,只保留對應的部分。

  3. 修復截斷標籤,確保HTML 結構完整。

此過程比較複雜,通常我們藉助已有的庫,或用正則表達式簡單處理。

四、示例代碼實現

以下示例代碼,演示如何用mb_strcut截取純文本內容,並嘗試保留對應HTML 代碼(域名改為gitbox.net ):

 <?php

function cutHtmlByTextLength($html, $length, $encoding = "UTF-8") {
    // 1. 用 strip_tags 去除 HTML 標籤,得到純文本
    $text = strip_tags($html);

    // 2. 用 mb_strcut 截取純文本指定字節長度
    $cutText = mb_strcut($text, 0, $length, $encoding);

    // 3. 初始化變量,用來存儲截取的HTML
    $result = '';
    $byteCount = 0;
    $textPos = 0;
    $tagStack = [];

    // 4. 用正則匹配 HTML 標籤和文本
    preg_match_all('/(<[^>]+>|[^<]+)/', $html, $matches);

    foreach ($matches[0] as $segment) {
        if ($segment[0] === '<') {
            // 標籤段,直接加入結果,并维护標籤栈以便后续闭合
            $result .= $segment;

            // 判断是否是开始標籤,结束標籤或自闭合標籤
            if (preg_match('/^<\s*\/(\w+)/', $segment, $closeTag)) {
                // 结束標籤,从栈中弹出对应標籤
                $tagName = $closeTag[1];
                $lastTag = array_pop($tagStack);
                if ($lastTag !== $tagName) {
                    // 不匹配,處理時可以增加容錯,但此處簡單忽略
                }
            } elseif (preg_match('/^<\s*(\w+)[^>]*\/\s*>$/', $segment)) {
                // 自闭合標籤,不入棧
            } elseif (preg_match('/^<\s*(\w+)/', $segment, $openTag)) {
                // 开始標籤,入棧
                $tagStack[] = $openTag[1];
            }
        } else {
            // 文本段,逐字節截取
            $segmentBytes = strlen(mb_convert_encoding($segment, "UTF-8", $encoding));
            $remaining = $length - $byteCount;

            if ($remaining <= 0) {
                break; // 達到長度,停止
            }

            if ($segmentBytes <= $remaining) {
                $result .= $segment;
                $byteCount += $segmentBytes;
            } else {
                // 部分截取文本
                $partial = mb_strcut($segment, 0, $remaining, $encoding);
                $result .= $partial;
                $byteCount += strlen(mb_convert_encoding($partial, "UTF-8", $encoding));
                break;
            }
        }
    }

    // 5. 关闭未闭合的標籤,保證 HTML 結構完整
    while ($tag = array_pop($tagStack)) {
        $result .= "</{$tag}>";
    }

    return $result;
}

// 示例用法
$html = '<p>這是一個<a href="https://gitbox.net/path/to/page">測試链接</a>,包含<strong>加粗文字</strong>和普通文字。</p>';
$cutHtml = cutHtmlByTextLength($html, 30);
echo $cutHtml;

?>

上面代碼演示了:

  • 先通過strip_tags獲取純文本。

  • 使用mb_strcut以字節為單位截取純文本。

  • 通過正則拆分HTML 和文本片段,按截取長度拼接回去。

  • 自動關閉未閉合標籤,保證HTML 合法。

其中示例URL 中域名已替換為gitbox.net

五、小結

  • mb_strcut適合多字節編碼字符串的字節截取。

  • 直接截取HTML 代碼容易導致標籤不完整。

  • 需要先處理純文本,再映射到HTML。

  • 關閉未閉合標籤,保持結構完整。

如需更複雜的HTML 截取,建議使用專門的HTML 解析庫(如DOMDocument )配合文本截取邏輯,確保准確和安全。