用户
 找回密码
 入住 CI 中国社区
搜索
查看: 3777|回复: 3
收起左侧

这个函数看不明白 求解释??

[复制链接]
发表于 2011-11-2 16:48:23 | 显示全部楼层 |阅读模式
本帖最后由 小凡 于 2011-11-2 16:49 编辑

public static function fix_html($string)
    {
        //关闭自闭合标签
        $startPos = strrpos($string, "<");

        if (false == $startPos)
        {
            return $string;
        }

        $trimString = substr($string, $startPos);

        if (false === strpos($trimString, ">"))
        {
            $string = substr($string, 0, $startPos);
        }

        //非自闭合html标签列表   这个下面的过程 看不明白
        preg_match_all("/<([_0-9a-zA-Z-\:]+)\s*([^>]*)>/is", $string, $startTags);
        preg_match_all("/<\/([_0-9a-zA-Z-\:]+)>/is", $string, $closeTags);

        if (!empty($startTags[1]) && is_array($startTags[1]))
        {
            krsort($startTags[1]);
            $closeTagsIsArray = is_array($closeTags[1]);
            foreach ($startTags[1] as $key => $tag)
            {
                $attrLength = strlen($startTags[2][$key]);
                if ($attrLength > 0 && "/" == trim($startTags[2][$key][$attrLength - 1]))
                {
                    continue;
                }
                if (!empty($closeTags[1]) && $closeTagsIsArray)
                {
                    if (false !== ($index = array_search($tag, $closeTags[1])))
                    {
                        unset($closeTags[1][$index]);
                        continue;
                    }
                }
                $string .= "</{$tag}>";
            }
        }

        return preg_replace("/\<br\s*\/\>\s*\<\/p\>/is", '</p>', $string);
               
    }

发表于 2011-11-2 21:35:32 | 显示全部楼层
本帖最后由 qi_ruo 于 2011-11-2 22:23 编辑
PHP复制代码
$str = 'aaaa<div>bbbb<p>cccc<a href="#" alt="dddd">eeee<img src="pic.jpg">ffff</a>gggg<br /><br /></p>hhhh</divuuuu';
function fix_html($string)
{
    //关闭自闭合标签
    $startPos = strrpos($string, "<"); //查找最后一个 < 的位置
 
    if (false == $startPos)
    {
        return $string; //如果字符串中没有 < 便签 直接返回 不再检查
    }
 
    $trimString = substr($string, $startPos);  // 从最后一个 < 到字符串结尾
 
    if (false === strpos($trimString, ">"))
    {
        $string = substr($string, 0, $startPos);  //如果之间没有 > 便签 那这一段就不要了
    }
 
    //非自闭合html标签列表
    preg_match_all("/<([_0-9a-zA-Z-\:]+)\s*([^>]*)>/is", $string, $startTags);
    //第一个括号匹配标签名 第二个括号匹配属性
    //$startTags[1] 将存放所有起始标签的名字, 比如 [div, p, a, img, br]
    //$startTags[2] 将存放所有起始标签的属性, 比如 ['', '', 'href="#"', 'src="pic.jpg" / ', '/']
 
    preg_match_all("/<\/([_0-9a-zA-Z-\:]+)>/is", $string, $closeTags);
    //$closeTags[1] 将存放所有结束标签的名字 比如 [a, p]
 
    if (!empty($startTags[1]) && is_array($startTags[1]))  // 如果$startTags[1]为空的话 说明没有找到起始标签
    {
        krsort($startTags[1]); // 把$startTags[1]倒序排列 以便和结束标签对应处理 可以想象成一种栈的结构
        $closeTagsIsArray = is_array($closeTags[1]);
        foreach ($startTags[1] as $key => $tag)
        {
            $attrLength = strlen($startTags[2][$key]);  //该起始标签属性的长度
            if ($attrLength > 0 && "/" == trim($startTags[2][$key][$attrLength - 1])) // 要么属性的最后一个字符是 /
            {
                continue;  // 如果属性的最后一个字符为 / 比如  <img />  继续
            }
            if (!empty($closeTags[1]) && $closeTagsIsArray) // 要么有结束标签
            {
                if (false !== ($index = array_search($tag, $closeTags[1])))  // 能找到对应的结束标签
                {
                    unset($closeTags[1][$index]); // 从结束标签列表中去除
                    continue;
                }
            }
            $string .= "</{$tag}>";  // 到此说明没有结束标签 加上结束标签
        }
    }
 
    return preg_replace("/\<br\s*\/\>\s*\<\/p\>/is", '</p>', $string); // 如果 </p> 之前有<br /> 删除之, 但只删一个
}
 
复制代码


但也有些问题
比如 如果img 标签 写成了 <img src="#">  程序会修正为 <img src="#"></img> 而不是 <img src="#" />
该函数的功能只是负责标签合闭,也可以进一步完善,
可以参考http://www.barattalo.it/html-fixer/

发表于 2011-11-2 22:21:37 | 显示全部楼层
我也看不明白
 楼主| 发表于 2011-11-3 14:22:35 | 显示全部楼层
qi_ruo 发表于 2011-11-2 21:35
但也有些问题
比如 如果img 标签 写成了   程序会修正为  而不是
该函数的功能只是负责标签合闭,也可以 ...

3Q  谢谢啦

本版积分规则