zodream梦想开源/个人编程日记

zodream梦想开源/个人编程日记

简单的个人编程日记

马上订阅 zodream梦想开源/个人编程日记 RSS 更新: https://zodream.cn/blog/rss

截取html

2019年12月22日 22:31
编程技术

截取html

需求

从一段html 中截取指定长度的内容,

要求:

  1. 长度为不包括html标签的内容长度,即 innerTEXT 长度
  2. 保留相关标签,并进行闭合

代码

简单版代码


/**
 * 截取html, 标签不计入长度,自动闭合标签
 * @param string $html
 * @param int $length
 * @param string $endWith
 * @bug 本方法缺陷: 未进行严格标签判断 例如 < <gg data="<a>"
 * @example ::substr('<p>1111<div/>111<br>111<i class="444">11</i>111 55555</p>', 12)
 * @return string
 */
public static function substr(string $html, int $length, string $endWith = '...'): string {
    if ($length < 1) {
        return $endWith;
    }
    $maxLength = mb_strlen($html);
    if ($maxLength < $length) {
        return $html;
    }
    $result = '';
    $n = 0;
    $unClosedTags = [];
    $isCode = false; // 是不是HTML代码
    $isHTML = false; // 是不是HTML特殊字符,如
    $notClosedTags = ['area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'link', 'meta', 'param', 'embed', 'command', 'keygen', 'source', 'track', 'wbr'];
    $tag = '';
    for ($i = 0; $i < $maxLength; $i++) {
        $char = mb_substr($html, $i, 1);
        if ($char == '<') {
            // 进入标签
            $isCode = true;
            $tag = '';
        }
        else if ($char == '&') {
            $isHTML = true;
        }
        else if ($char == '>' && $isCode) {
            $n = $n - 1;
            $isCode = false;
            $tag = explode(' ', $tag, 2)[0];
            if (substr($tag, 0, 1) === '/') {
                // 判断是否时结束标签, 倒序找到邻近开始标签,进行移除
                for ($j = count($unClosedTags) - 1; $j >= 0; $j --)...

剩余内容已隐藏

查看完整文章以阅读更多