作者:深碍是碍u不是爱 | 来源:互联网 | 2018-03-23 19:03
分析HTML代码HTML一般包括以下的部分:标签,以包裹文档声明、注释等格式半开标签闭合标签内容,非以包裹,这一部分内容中多空格是无效果的PHP正则分解html代码html代码是以标签为界限的,所以,
分析HTML代码
HTML一般包括以下的部分:
标签,以<>包裹
文档声明、注释等格式
半开标签<..../>
闭合标签
内容,非以<>包裹,这一部分内容中多空格是无效果的
PHP正则分解html代码
html代码是以标签为界限的,所以,只要按标签分解就可以了。在PHP中使用preg_split:
$segments = preg_split("/(<[^>]+?>)/si",$html, null,PREG_SPLIT_NO_EMPTY| PREG_SPLIT_DELIM_CAPTURE);
例如,以下的代码
$html = <<
关注WEB,体悟生活;珍惜生命,远离代码。
HTML;
print_r(preg_split("/(<[^>]+?>)/si",$html, -1,PREG_SPLIT_NO_EMPTY| PREG_SPLIT_DELIM_CAPTURE));
会产生如下的输出:
Array
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] =>
[5] =>
[6] =>
[9] =>
[10] =>
[11] =>
[12] =>
[13] =>
[14] =>
[15] =>
[16] =>
[17] =>
[18] =>
[19] =>
[20] =>
[23] =>
[24] =>
[27] =>
[28] =>
[31] =>
[32] =>
[35] =>
[36] =>
[41] =>
[42] =>
[43] => 关注WEB,体悟生活;珍惜生命,远离代码。
[44] =>
[45] =>
[46] =>
[47] =>
[48] =>
[49] =>
[50] =>
[51] =>
[52] =>
[53] =>
)
最简单但有损的PHP压缩
最简单的压缩就是直接连接所有的非空项,同时非标签去掉所有的空白:
$compressed = array();
foreach($segments as $seg)
{
$seg = trim($seg);
if($seg)
{
//非标签中的空白是无效的字符
$compressed[] = $seg[0] === &#39;<&#39; ? $seg : preg_replace(&#39;!\s!&#39;,&#39;&#39;,$seg);
}
}
return join(&#39;&#39;,$compress);
如以上的HTML通过这样的压缩生成的代码是(为了方便显示,我手动将它们断行了):
关注WEB,体悟生活;珍惜生命,远离代码。
正常情况下这没错,但是也有“不正常”的情况:遇到不能去掉空白的内容时。比如script、code、pre、style是不可以去掉空白的,这时,就要使用栈进行压缩了:
使用栈进行安全压缩html
使用栈的规则是:<..>标签入栈,标签出栈,和<../>不理,但有一种可能的情况是,<../>不一定有结尾的反斜杠如:
都是可以的,这时就要特殊的处理这种情况:
关注WEB,体悟生活;珍惜生命,远离代码。
var say = "Hello world!";
print say;
HTML;
$segments = preg_split("/(<[^>]+?>)/si",$html, -1,PREG_SPLIT_NO_EMPTY| PREG_SPLIT_DELIM_CAPTURE);
$compressed = array();
$stack = array();
$tag = &#39;&#39;;
$half_open = array(&#39;meta&#39;,&#39;input&#39;,&#39;link&#39;,&#39;img&#39;,&#39;br&#39;);
$cannot_compress = array(&#39;pre&#39;,&#39;code&#39;,&#39;script&#39;,&#39;style&#39;);
foreach($segments as $seg)
{
if(trim($seg) === &#39;&#39;)
{
continue;
}
//<.../>
if(preg_match("!<([a-z0-9]+)[^>]*?/>!si",$seg, $match))
{
//$tag = self::format_tag($match[1]);
format_tag($match[1]);
$compressed[] = $seg;
}
else if(preg_match("!([a-z0-9]+)[^>]*?>!si",$seg,$match))//
{
$tag = format_tag($match[1]);
if(count($stack) > 0 && $stack[count($stack)-1] == $tag)
{
array_pop($stack);
$compressed[] = $seg;
}
//这里再最好加一段判断,可以用于修复错误的html
//...
}
else if(preg_match("!<([a-z0-9]+)[^>]*?>!si",$seg,$match))//<>
{
$tag = format_tag($match[1]);
//半闭合标签不需要入栈,如
,
if(!in_array($tag, $half_open))
{
array_push($stack,$tag);
}
$compressed[] = $seg;
}
else if(preg_match("~]*>~", $seg))
{
//文档声明和注释,注释也不能删除,如
$compressed[] = $seg;
}
else
{
$compressed[] = in_array($tag, $cannot_compress) ? $seg : preg_replace(&#39;!\s!&#39;, &#39;&#39;, $seg);
}
}
function format_tag($tag)
{
return trim(strtolower($tag));
}
echo join(&#39;&#39;,$compressed);
以上的代码产生如下的输出(为了方便显示,我手工断行了):
关注WEB,体悟生活;珍惜生命,远离代码。
var say = "Hello world!";
print say;
最安全的HTML压缩
当然,以上的代码正确运行的基础是:HTML都是正确合法的,没有出现如等,但是在普通应用是没有问题的,如果需要安全的压缩HTML代码,可以使用HTML解析库进行修复并进行压缩