免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2247 | 回复: 2
打印 上一主题 下一主题

[code] HTML_fixed,自动修补HTML代码片段 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-04-14 22:28 |只看该作者 |倒序浏览
在一些WEB程序写作中经常碰到要强行读取某个HTML文件的一部分,或者由于输入超长会被程序
砍断,而使用者经常直接粘贴代码而不会去注意....往往导致页面显示是出现意外的错误. 这是最近
写的一个小函数,效率上并没有特别去斟酌...


  1. <?php
  2. // 修复一段残缺的 HTML 代码, 主要用于HTML代码被砍断的情况
  3. // $Id: http_header.php,v 1.1 2004/07/25 12:39:57 hightman Exp $
  4. function html_fixed($buf) {
  5.     $len = strlen($buf);
  6.    
  7.     $tag_open  = false;
  8.     $tag_alone = Array("br", "meta", "base", "hr", "!", "img", "input");
  9.     $tag_stack = Array();

  10.     $tag_tmp = "";
  11.     $ret = "";

  12.     while ($i < $len) {
  13.         $ch = $buf{$i};
  14.         $ret .= $ch;
  15.         $i++;
  16.         if ($ch == '<') {
  17.             $tag_tmp = "";

  18.             // 之前的标签没关先关闭
  19.             if ($tag_open == true) {
  20.                 $ret .= ">;";
  21.             }

  22.             // 打开标签
  23.             $tag_open = true;

  24.             // get tag_flag
  25.             while ($i < $len) {
  26.                 $ch = $buf{$i};
  27.                 $i++;

  28.                 if ($ch == '<') {
  29.                     $ret .= ">;";
  30.                     $tag_open = false;
  31.                     $i--;
  32.                 }
  33.                 else {
  34.                     $ret .= $ch;
  35.                 }

  36.                 if ($ch == '>;') $tag_open = false;

  37.                 // tag_end
  38.                 if (strchr(" \t\r\n->;<", $ch))
  39.                     break;
  40.                 $tag_tmp .= $ch;
  41.             }
  42.             // get tag_flag end

  43.             // after get tag
  44.             if (!empty($tag_tmp)) {
  45.                 $tag_tmp = strtolower($tag_tmp);
  46.                 if (substr($tag_tmp, 0, 1) == "/") {
  47.                     // 闭合型标签
  48.                     $tmp_stack = Array();
  49.                     while ($tmp = array_pop($tag_stack)) {
  50.                         if (!strcmp($tmp, $tag_tmp))
  51.                             break;
  52.                         array_push($tmp_stack, $tmp);
  53.                     }

  54.                     while ($tmp = array_pop($tmp_stack)) {
  55.                         array_push($tag_stack, $tmp);
  56.                     }
  57.                 }
  58.                 else if (!in_array($tag_tmp, $tag_alone)) {
  59.                     // 存入堆栈待关闭
  60.                     array_push($tag_stack, $tag_tmp);
  61.                 }
  62.             }
  63.         }
  64.         else if ($ch == '>;') {
  65.             // 关闭标签
  66.             $tag_open = false;
  67.         }
  68.     } // end while

  69.     // 最后看看 tag_open ?? 和 tag_stack ??
  70.     if ($tag_open) {
  71.         $ret .= ">;";
  72.     }

  73.     while ($tmp = array_pop($tag_stack)) {
  74.         $ret .= "</{$tmp}>;";
  75.     }
  76.     $ret .= "\n";

  77.     return $ret;
  78. }
  79. ?>;
复制代码

论坛徽章:
0
2 [报告]
发表于 2005-04-16 05:44 |只看该作者

[code] HTML_fixed,自动修补HTML代码片段

呵呵, 不错的东西, 但是需要进一步优化,现在的 tag_open 只是一个, 所以不能支持多重修补, 而且有点小BUG.

当:

  1. $buf ='
  2. <table width="100%" cellspacing="2" cellpadding="2" border="0"  align="center">;
  3.   <tr>;<a href="
  4.         <td align="left" valign="bottom" colsp';
复制代码

的时候,替换结果:
为:

  1. <table width="100%" cellspacing="2" cellpadding="2" border="0"  align="center">;
  2.   <tr>;<a href="
  3.         <>;td align="left" valign="bottom" colsp>;</td>;</a>;</tr>;</table>;
复制代码


感觉思路非常不错, 非常高兴看到这样的原创,下次有了新的函数告诉我,我转到我的论坛上去,呵呵

论坛徽章:
0
3 [报告]
发表于 2005-04-17 15:12 |只看该作者

[code] HTML_fixed,自动修补HTML代码片段

en,的确有bug,谢谢指出,现已做进一步修正,代码如下:

  1. function html_fixed($buf) {
  2.     $len = strlen($buf);
  3.    
  4.     $tag_open  = false;
  5.     $tag_alone = Array("br", "meta", "base", "hr", "!", "img", "input");
  6.     $tag_stack = Array();

  7.     $tag_tmp = "";
  8.     $ret = "";

  9.     while ($i < $len) {
  10.         $ch = $buf{$i};
  11.         $i++;
  12.         if ($ch == '<') {
  13.             $tag_tmp = "";

  14.             // 之前的标签没关先关闭
  15.             if ($tag_open == true) {
  16.                 $ret .= ">;";
  17.             }
  18.             
  19.             $ret .= $ch;

  20.             // 打开标签
  21.             $tag_open = true;

  22.             // get tag_flag
  23.             while ($i < $len) {
  24.                 $ch = $buf{$i};
  25.                 $i++;

  26.                 if ($ch == '<') {
  27.                     $ret .= ">;";
  28.                     $tag_open = false;
  29.                     $i--;
  30.                 }
  31.                 else {
  32.                     $ret .= $ch;
  33.                 }

  34.                 if ($ch == '>;') $tag_open = false;

  35.                 // tag_end
  36.                 if (strchr(" \t\r\n->;<", $ch))
  37.                     break;               
  38.                 $tag_tmp .= $ch;
  39.             }
  40.             // get tag_flag end

  41.             // after get tag
  42.             if (!empty($tag_tmp)) {
  43.                 $tag_tmp = strtolower($tag_tmp);
  44.                 if (substr($tag_tmp, 0, 1) == "/") {
  45.                     // 闭合型标签
  46.                     $tmp_stack = Array();
  47.                     while ($tmp = array_pop($tag_stack)) {
  48.                         if (!strcmp($tmp, $tag_tmp))
  49.                             break;
  50.                         array_push($tmp_stack, $tmp);
  51.                     }

  52.                     while ($tmp = array_pop($tmp_stack)) {
  53.                         array_push($tag_stack, $tmp);
  54.                     }
  55.                 }
  56.                 else if (!in_array($tag_tmp, $tag_alone)) {
  57.                     // 存入堆栈待关闭
  58.                     array_push($tag_stack, $tag_tmp);
  59.                 }
  60.             }
  61.         }
  62.         else {
  63.             if ($ch == '>;') {
  64.                 // 关闭标签
  65.                 $tag_open = false;
  66.             }
  67.             $ret .= $ch;
  68.         }
  69.     } // end while

  70.     // 最后看看 tag_open ?? 和 tag_stack ??
  71.     if ($tag_open) {
  72.         $ret .= ">;";
  73.     }

  74.     while ($tmp = array_pop($tag_stack)) {
  75.         $ret .= "</{$tmp}>;";
  76.     }
  77.     $ret .= "\n";

  78.     return $ret;
  79. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP