[正则表达式] 可以解析HTML/XHTML页面的所有元素和结构的Regular Expression!

哈哈,继 昨天的那个正则表达式 之后又写了一个更长的Regular
Expression,全长527,是用于查找出所有的XHTML/HTML的标记外面的所有空格,并将之转换为 的。
希望这个能够解决dudu提的一个cnblogs的bug:)即使不能解决问题也算是对System.Text.RegularExpression.Regex的一个练笔了:)

这两天又花了点时间看了一下Regular Expression的语法,顺便写了一个用于
匹配出all continuous white-spaces outside the C-style multiline comment
blocks的Regex。这个是我个人到目前为止写的一个算是最复杂的正则表达式了,贴出来与大家交流:

(?:(?:\<(?:Style)(?:\s+(?:[\w-]+)(?:=(?:[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)(?:[\s\S]*?)(?:\</(?:Style)\>))|(?:(?:\<(?:script)(?:\s+(?:[\w-]+)(?:=(?:[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)(?:[\s\S]*?)(?:\</(?:script)\>))|(?:\<!(?:[\w-]+)(?:\s+(?:[\w-]+|\”[\s\S]*?\”|\'[\s\S]*?\’))*\s*\>)|(?:\<!–[\s\S]*?–\>)|(?:\<(?:[\w-]+)(?:\s+(?:[\w-]+)(?:=(?:[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)|(?:\</(?:[\w-]+)\>)|(?:\<!\[CDATA\[(?:[\s\S]*?)\]\]\>)|(?:(?:(?<blank>[
]+)|[^ \<\>])+)

(?<=(?:\*/)(?:[^/\*]|(?<!/)\*|/(?!\*))*)\s+(?=(?:[^\*/]|(?<!\*)/|\*(?!/))*(?:/\*))|(?<=\A(?:[^/\*]|(?<!/)\*|/(?!\*))*)\s+(?=(?:[^\*/]|(?<!\*)/|\*(?!/))*(?:/\*))|(?<=(?:\*/)(?:[^/\*]|(?<!/)\*|/(?!\*))*)\s+(?=(?:[^\*/]|(?<!\*)/|\*(?!/))*\z)|(?<=\A(?:[^/\*]|(?<!/)\*|/(?!\*))*)\s+(?=(?:[^\*/]|(?<!\*)/|\*(?!/))*\z)
当然小弟我对Regular
Expression接触不多,这个Regex应该还有问题,肯定有些特殊的情况没有考虑到,请大家指正:)

这个正则表达式虽然很长,但可不是我用手code出来的哦,是我写的程序产生的,代码如下:)

另外还有个问题想请教大家。我在看MSDN中Regular Expression Language
Elements
的帮助的时候,有一个Grouping Construct没有看懂:

图片 1
图片 2
public static string ReplaceSpace(string content)
图片 3图片 4
图片 5{
图片 6
string tag = @”(?:[\w-:]+)”;
图片 7
string attribute =
@”(?:[\w-:]+)(?:=(?:[^\s\>\<]*|\””[\s\S]*?\””|\'[\s\S]*?\’))?”;
图片 8
string name = @”(?:[\w-:]+)”;
图片 9
string argument =
@”(?:[\w-:]+|\””[\s\S]*?\””|\'[\s\S]*?\’)”;
图片 10
图片 11
string beginningTag = @”(?:\<” + tag + @”(?:\s+” +attribute +
@”)*\s*(?:/)?\>)”;
图片 12
string endingTag = @”(?:\</” + tag + @”\>)”;
图片 13
string xmlComment = @”(?:\<!–[\s\S]*?–\>)”;
图片 14
string xmlDirective = @”(?:\<!” +name + @”(?:\s+” +argument +
@”)*\s*\>)”;
图片 15
string xmlCData =
@”(?:\<!\[CDATA\[(?:[\s\S]*?)\]\]\>)”;
图片 16
string styleBlock = @”(?:(?:\<(?:Style)(?:\s+” +attribute +
@”)*\s*(?:/)?\>)(?:[\s\S]*?)(?:\</(?:Style)\>))”;
图片 17
string scriptBlock = @”(?:(?:\<(?:script)(?:\s+” +attribute +
@”)*\s*(?:/)?\>)(?:[\s\S]*?)(?:\</(?:script)\>))”;
图片 18
string xmlLiteral = @”(?:(?:(?<blank>[ ]+)|[^
\<\>])+)”;
图片 19
图片 20
string pattern = styleBlock + “|” + scriptBlock + “|” + xmlDirective +
“|” + xmlComment + “|” + beginningTag + “|” + endingTag + “|” + xmlCData

(?>   ) Nonbacktracking subexpression (also known as a "greedy" subexpression). The subexpression is fully matched once, and then does not participate piecemeal in backtracking. (That is, the subexpression matches only strings that would be matched by the subexpression alone.)
  • “|” + xmlLiteral;
    图片 21
    图片 22
    Regex r = new Regex(pattern, RegexOptions.IgnoreCase |
    RegexOptions.Compiled);
    图片 23
    图片 24
    MatchCollection mc = r.Matches(content);
    图片 25
    图片 26
    StringBuilder sb = new StringBuilder(content.Length + 1024);
    图片 27
    foreach (Match m in mc)
    图片 28图片 29
    图片 30{
    图片 31
    if (m.Groups[“blank”].Captures.Count > 0)
    图片 32图片 33
    图片 34{
    图片 35
    sb.Append(m.Value.Replace(” “, ” “));
    图片 36
    }
    图片 37
    else
    图片 38图片 39
    图片 40{
    图片 41
    sb.Append(m.Value);
    图片 42
    }
    图片 43
    }
    图片 44
    return sb.ToString();
    图片 45
    }
    图片 46

如果有谁知道它的含义,请告知。我想这个不仅是我一个人想知道:)当然另外如果有人在学习正则表达式的过程如果遇到过什么问题,也欢迎提出来交流一下:)

最后,再给个更长的(全长765)正则表达式,这个算是我写的最长的正则表达式了。其实上面给出的第一个Regex是下面这个的一个专用于捕获blank的简化版本。
虽然长,但很有用,可以解析出整个XHTML/HTML页面的所有元素和结构来:)解析后的内容都分别保存在named
groups中了,可以通过match.Groups[“name”];来提取,比如match.Groups[“tag”];match.Groups[“attribute”];match.Groups[“Style_Block”;match.Groups[“XML_Comment”];等,感兴趣的不妨试一试就知道了:)

下面是MSDN中的Regular Expression Language Elements的Reference:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconregularexpressionslanguageelements.asp

(?#Copyright 2005, by Laser
Lu.)(?<Style_Block>(?<begin>\<(?<tag>style)(?:\s+(?<attribute>[\w-:]+)(?:=(?<value>[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)(?<body>[\s\S]*?)(?<end>\</\k<tag>\>))|(?<Script_Block>(?<begin>\<(?<tag>script)(?:\s+(?<attribute>[\w-:]+)(?:=(?<value>[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)(?<body>[\s\S]*?)(?<end>\</\k<tag>\>))|(?<XML_Directive>\<!(?<name>[\w-:]+)(?:\s+(?<argument>[\w-:]+|\”[\s\S]*?\”|\'[\s\S]*?\’))*\s*\>)|(?<XML_Comment>\<!–[\s\S]*?–\>)|(?<Beginning_Tag>\<(?<tag>[\w-:]+)(?:\s+(?<attribute>[\w-:]+)(?:=(?<value>[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)|(?<Ending_Tag>\</(?<tag>[\w-:]+)\>)|(?<XML_CDATA>\<!\[CDATA\[(?<data>[\s\S]*?)\]\]\>)|(?<XML_Literal>(?:(?<blank>[
]+)|[^ \<\>])+)

最后,给大家推荐两个关于Regular Expression的很不错的学习网站:)
http://www.regexlib.com/
http://www.regular-expressions.info/

关于以上的两个Regex的相关说明,应该说功能还是比较强大的了:
1。这两个正则表达式能够解析最好是HTML/XHTML格式,如果是其他格式的字符串,有可能会运行不正常;
2。支持识别的标记有:普通的HTML标记,<!–HTML注释–>,<!XML指令>,<![CDATA[
… ]]>,标记或指令的标识符支持[a-zA-Z0-9_-:];
3。支持name=value和单独一个name的attribute,能够识别出””或”包括的属性值;
4。针对<style></style>和<script></script>标记包含的内容进行特殊处理,也就是所有的CSS和Script代码将原封不动的作为整体捕获。

[05/04/20 Update]:
哈哈, 今天又写了一个更长的Regular
Expression,全长527,是用于查找出所有的XHTML/HTML的标记外面的所有空格,并将之转换为 的。


(?:(?:\<(?:Style)(?:\s+(?:[\w-]+)(?:=(?:[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)(?:[\s\S]*?)(?:\</(?:Style)\>))|(?:(?:\<(?:script)(?:\s+(?:[\w-]+)(?:=(?:[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)(?:[\s\S]*?)(?:\</(?:script)\>))|(?:\<!(?:[\w-]+)(?:\s+(?:[\w-]+|\”[\s\S]*?\”|\'[\s\S]*?\’))*\s*\>)|(?:\<!–[\s\S]*?–\>)|(?:\<(?:[\w-]+)(?:\s+(?:[\w-]+)(?:=(?:[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)|(?:\</(?:[\w-]+)\>)|(?:\<!\[CDATA\[(?:[\s\S]*?)\]\]\>)|(?:(?:(?<blank>[
]+)|[^ \<\>])+)

这个正则表达式虽然很长,但可不是我用手code出来的哦,是我写的程序产生的,代码如下:)

图片 47
图片 48
public static string ReplaceSpace(string content)
图片 49图片 50
图片 51{
图片 52
string tag = @”(?:[\w-:]+)”;
图片 53
string attribute =
@”(?:[\w-:]+)(?:=(?:[^\s\>\<]*|\””[\s\S]*?\””|\'[\s\S]*?\’))?”;
图片 54
string name = @”(?:[\w-:]+)”;
图片 55
string argument =
@”(?:[\w-:]+|\””[\s\S]*?\””|\'[\s\S]*?\’)”;
图片 56
图片 57
string beginningTag = @”(?:\<” + tag + @”(?:\s+” +attribute +
@”)*\s*(?:/)?\>)”;
图片 58
string endingTag = @”(?:\</” + tag + @”\>)”;
图片 59
string xmlComment = @”(?:\<!–[\s\S]*?–\>)”;
图片 60
string xmlDirective = @”(?:\<!” +name + @”(?:\s+” +argument +
@”)*\s*\>)”;
图片 61
string xmlCData =
@”(?:\<!\[CDATA\[(?:[\s\S]*?)\]\]\>)”;
图片 62
string styleBlock = @”(?:(?:\<(?:Style)(?:\s+” +attribute +
@”)*\s*(?:/)?\>)(?:[\s\S]*?)(?:\</(?:Style)\>))”;
图片 63
string scriptBlock = @”(?:(?:\<(?:script)(?:\s+” +attribute +
@”)*\s*(?:/)?\>)(?:[\s\S]*?)(?:\</(?:script)\>))”;
图片 64
string xmlLiteral = @”(?:(?:(?<blank>[ ]+)|[^
\<\>])+)”;
图片 65
图片 66
string pattern = styleBlock + “|” + scriptBlock + “|” + xmlDirective +
“|” + xmlComment + “|” + beginningTag + “|” + endingTag + “|” + xmlCData

  • “|” + xmlLiteral;
    图片 67
    图片 68
    Regex r = new Regex(pattern, RegexOptions.IgnoreCase |
    RegexOptions.Compiled);
    图片 69
    图片 70
    MatchCollection mc = r.Matches(content);
    图片 71
    图片 72
    StringBuilder sb = new StringBuilder(content.Length + 1024);
    图片 73
    foreach (Match m in mc)
    图片 74图片 75
    图片 76{
    图片 77
    if (m.Groups[“blank”].Captures.Count > 0)
    图片 78图片 79
    图片 80{
    图片 81
    sb.Append(m.Value.Replace(” “, ” “));
    图片 82
    }
    图片 83
    else
    图片 84图片 85
    图片 86{
    图片 87
    sb.Append(m.Value);
    图片 88
    }
    图片 89
    }
    图片 90
    return sb.ToString();
    图片 91
    }
    图片 92

希望这个能够解决今天dudu提的一个cnblogs的bug:)即使不能解决问题也算是对System.Text.RegularExpression.Regex的一个练笔了:)

最后,再给个更长的(全长765)正则表达式,这个算是我写的和见过的最长的正则表达式了。
虽然长,但很有用,可以解析出整个XHTML/HTML页面的元素和结构来:)

(?#Copyright 2005, by Laser
Lu.)(?<Style_Block>(?<begin>\<(?<tag>style)(?:\s+(?<attribute>[\w-:]+)(?:=(?<value>[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)(?<body>[\s\S]*?)(?<end>\</\k<tag>\>))|(?<Script_Block>(?<begin>\<(?<tag>script)(?:\s+(?<attribute>[\w-:]+)(?:=(?<value>[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)(?<body>[\s\S]*?)(?<end>\</\k<tag>\>))|(?<XML_Directive>\<!(?<name>[\w-:]+)(?:\s+(?<argument>[\w-:]+|\”[\s\S]*?\”|\'[\s\S]*?\’))*\s*\>)|(?<XML_Comment>\<!–[\s\S]*?–\>)|(?<Beginning_Tag>\<(?<tag>[\w-:]+)(?:\s+(?<attribute>[\w-:]+)(?:=(?<value>[^\s\>\<]*|\”[\s\S]*?\”|\'[\s\S]*?\’))?)*\s*(?:/)?\>)|(?<Ending_Tag>\</(?<tag>[\w-:]+)\>)|(?<XML_CDATA>\<!\[CDATA\[(?<data>[\s\S]*?)\]\]\>)|(?<XML_Literal>(?:(?<blank>[
]+)|[^ \<\>])+)