2009年11月2日

HTML是否闭合以及自动修复

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Diagnostics;

namespace 查HTML是否闭合
{


    
class TagsList
    {
        
private ArrayList data;

        
public int Size
        {
            
get
            {
                
return data.Count;
            }
        }

        
public TagsList()
        {
            data 
= new ArrayList();
        }

        
public void add(String str)
        {
            data.Add(str);
        }

        
public string get(int index)
        {
            
if (index < data.Count)
                
return (string)data[index];
            
else
                
return null;
        }

        
public bool remove(string str)
        {
            
if (data.IndexOf(str) == -1return false;
            data.Remove(str);
            
return true;
        }

        
public void remove(int index)
        {
            data.RemoveAt(index);
        }
    }

    
public class TagsChecker
    {
        
public static bool check(string str)
        {
            TagsList[] unclosedTags 
= getUnclosedTags(str);

            
if (unclosedTags[0].Size != 0)
            {
                
return false;
            }
            
for (int i = 0; i < unclosedTags[1].Size; i++)
            {
                
if (unclosedTags[1].get(i) != null)
                    
return false;
            }

            
return true;
        }

        
public static string fix(String str)
        {
            StringBuilder fixeds 
= new StringBuilder(); // 存放修复后的字符串
            TagsList[] unclosedTags = getUnclosedTags(str);

            
// 生成新字符串
            for (int i = unclosedTags[0].Size - 1; i > -1; i--)
            {
                fixeds.Append(
"<" + unclosedTags[0].get(i) + ">");
            }

            fixeds.Append(str);

            
for (int i = unclosedTags[1].Size - 1; i > -1; i--)
            {
                String s 
= null;
                
if ((s = unclosedTags[1].get(i)) != null)
                {
                    fixeds.Append(
"</" + s + ">");
                }
            }

            
return fixeds.ToString();
        }

        
private static TagsList[] getUnclosedTags(String str)
        {
            StringBuilder temp 
= new StringBuilder(); // 存放标签
            TagsList[] unclosedTags = new TagsList[2];
            unclosedTags[
0= new TagsList(); // 前不闭合,如有</div>而前面没有<div>
            unclosedTags[1= new TagsList(); // 后不闭合,如有<div>而后面没有</div>
            bool flag = false// 记录双引号"或单引号'
            char currentJump = ' '// 记录需要跳过''还是""

            
char current = ' ', last = ' '// 当前 & 上一个

            
// 开始判断
            for (int i = 0; i < str.Length; )
            {
                current 
= str[i++]; // 读取一个字符
                if (current == '"' || current == '\'')
                {
                    flag 
= flag ? false : true// 若为引号,flag翻转
                    currentJump = current;
                    
if (flag)
                    {
                        
while (i < str.Length && str[i++!= currentJump)
                            ; 
// 跳过引号之间的部分
                        flag = false;
                    }
                }
                
else if (current == '<')
                { 
// 开始提取标签
                    current = str[i++];
                    
if (current == '/')
                    { 
// 标签的闭合部分,如</div>
                        current = str[i++];

                        
// 读取标签
                        while (i < str.Length && current != '>')
                        {
                            temp.Append(current);
                            current 
= str[i++];
                        }

                        
// 从tags_bottom移除一个闭合的标签
                        if (!unclosedTags[1].remove(temp.ToString()))
                        { 
// 若移除失败,说明前面没有需要闭合的标签
                            unclosedTags[0].add(temp.ToString()); // 此标签需要前闭合
                        }
                        temp.Remove(
0, temp.Length); // 清空temp
                    }
                    
else
                    { 
// 标签的前部分,如<div>
                        last = current;
                        
while (i < str.Length && current != ' '
                                
&& current != ' ' && current != '>')
                        {
                            temp.Append(current);
                            last 
= current;
                            current 
= str[i++];
                        }

                        
// 已经读取到标签,跳过其他内容,如<div id=test>跳过id=test
                        while (i < str.Length && current != '>')
                        {
                            last 
= current;
                            current 
= str[i++];
                            
if (current == '"' || current == '\'')
                            { // 判断双引号
                                flag = flag ? false : true;
                                currentJump 
= current;
                                
if (flag)
                                { 
// 若引号不闭合,跳过到下一个引号之间的内容
                                    while (i < str.Length && str[i++!= currentJump)
                                        ;
                                    current 
= str[i++];
                                    flag 
= false;
                                }
                            }
                        }
                        
if (last != '/' && current == '>'// 判断这种类型:<TagName />
                            unclosedTags[1].add(temp.ToString());
                        temp.Remove(
0, temp.Length);
                    }
                }
            }
            
return unclosedTags;
        }
    }

    
class Program
    {
        
static void Main(string[] args)
        {


            Console.WriteLine(
"--功能测试--");
            
//string str1 = "tt</u>ss</a>aa<div name=\"<test>\" id='3' other='<test>'><b>sff";
            string str1 = "<p>tt<table><tr><td>kdkf</td></tr><tr><td>323</td></p>";
            
string str2 = "tt<u>ss</u><div id=test name=\"<test>\"><a>fds</a></div>";
            Console.WriteLine(
"检查文本 " + str1);
            Console.WriteLine(
"结果:" + TagsChecker.check(str1));
            Console.WriteLine(
"检查文本 " + str2);
            Console.WriteLine(
"结果:" + TagsChecker.check(str2));
            Console.WriteLine(
"修复文本 " + str1);
            Console.WriteLine(
"结果:" + TagsChecker.fix(str1));

            
for (int i = 0; i < 10; i++)
            {
                str1 
+= str1;
            }


            Console.WriteLine();
            Console.WriteLine(
"--效率测试--");
            Console.WriteLine(
"文本长度:" + str1.Length);



            
long t1 = DateTime.Now.Ticks;
            
bool closed = TagsChecker.check(str1);
            
long t2 = DateTime.Now.Ticks;
            String fixedStr 
= TagsChecker.fix(str1);
            
long t3 = DateTime.Now.Ticks;
            Console.WriteLine(
"检查用时:" + (t2 - t1) + " 毫秒 结果:" + closed);
            Console.WriteLine(
"修复用时:" + (t3 - t2) + " 毫秒");


        }
    }
}

posted @ 2009-11-02 17:21 真不懂 阅读(1446) 评论(2) 推荐(1) 编辑

2009年6月24日

用Jquery重写windows.alert方法

摘要: 已经在 IE8 , firefox3.0.11下面测试通过[代码]注:以上引用js与CSS的jquery插件,出自:http://www.cnblogs.com/chenjinfa/archive/2009/03/17/1414178.html 阅读全文

posted @ 2009-06-24 13:48 真不懂 阅读(8601) 评论(22) 推荐(0) 编辑

2009年6月23日

JQuery 动态加载CSS与JS脚本文件

摘要: [代码]注:转自:http://www.cnblogs.com/chenjinfa/archive/2009/03/17/1414178.html 阅读全文

posted @ 2009-06-23 17:00 真不懂 阅读(16343) 评论(3) 推荐(0) 编辑

IIS7 修改默认文档,不修改web.config

摘要: 若不想改变web.config,直接修改继承的默认文档,最方便的方法就是使用appcmd.exe方法如下:用管理员权限运行CMD.exe进入目录:c:\windows\system32\inetsrv 添加一个默认文档进入列表的语句是:appcmd set config /section:defaultDocument /+files.[value='index.html']这个例句添加index... 阅读全文

posted @ 2009-06-23 09:34 真不懂 阅读(3270) 评论(0) 推荐(0) 编辑

2009年6月8日

待改进的alert与confirm

摘要: [代码] 阅读全文

posted @ 2009-06-08 13:15 真不懂 阅读(196) 评论(0) 推荐(0) 编辑

2009年6月6日

jquery扩展,显示模态DIV层

摘要: jquery扩展,显示模态DIV层:下面是 jquery.divbox.js 内的代码:[代码]下面是示例文件 demo.html 代码:[代码] 阅读全文

posted @ 2009-06-06 13:59 真不懂 阅读(4432) 评论(7) 推荐(0) 编辑

2009年6月5日

关于游标

摘要: --------------关于游标------------------------------------更新state=0的用户积分declarecurcursorforselectjifen,useridfromtb_lipinjorderwherelipinjID=@idandstate=0opencurfetchnextfromcurinto@temJifen,@temUserIDwhi... 阅读全文

posted @ 2009-06-05 11:03 真不懂 阅读(81) 评论(0) 推荐(0) 编辑

存储过程中分隔循环处理,用于批量操作数据

摘要: declare @tem varchar(300)declare @Index intset @tem='1,12,22,13,33,'declare @Count intset @Count = 1set @Index = charindex(',',@tem)while @Index > 0beginselect substring(@tem,@Count,@Index - @Count... 阅读全文

posted @ 2009-06-05 10:55 真不懂 阅读(212) 评论(0) 推荐(0) 编辑

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示