当前位置: 首页> 最新文章列表> 如何使用 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)配合文本截取逻辑,确保准确和安全。