mb_strcut以字節為單位截取字符串,與mb_substr不同的是, mb_strcut是按字節截取,常用於處理多字節編碼。
示例:
<?php
$str = "這是一個測試字符串";
echo mb_strcut($str, 0, 6, "UTF-8"); // 輸出:這是一個
?>
這裡的6 是字節數,中文字符在UTF-8 中一般佔3個字節,因此截取6字節等於截取2個漢字。
假設有一段HTML 代碼:
<?php
$html = "<p>這是一個<strong>測試</strong>字符串。</p>";
如果直接用mb_strcut截取,可能截斷在標籤中間:
$cut = mb_strcut($html, 0, 15, "UTF-8");
echo $cut;
這可能輸出不完整的標籤,比如<p>這是一個<strong>測,導致瀏覽器渲染出錯。
先把HTML 解析成純文本,用mb_strcut截取純文本內容。
根據截取後的文本長度,映射回原始HTML ,只保留對應的部分。
修復截斷標籤,確保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 )配合文本截取邏輯,確保准確和安全。