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)配合文本截取逻辑,确保准确和安全。