首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

这类嵌套正则怎么写?通过id属性获得一个标签块

2012-02-11 
这类嵌套正则如何写?通过id属性获得一个标签块需求:就是通过id获得一个html标签块。要处理的字符串:HTML co

这类嵌套正则如何写?通过id属性获得一个标签块
需求:就是通过id获得一个html标签块。

要处理的字符串:

HTML code
<html><body><div id="div1">        <div id="div2" style="background:Red;">                <div id="div3">                        <table id="table1">                                <tr>                                        <td>                                                <div id="div4" style="width:100px"></div>                                        </td>                                </tr>                        </table>                </div>        </div>        <div id="div5">                <a href="http://www.csdn.net">csdn</a>        </div></div><img src="http://www.csdn.net/Images/logo_csdn.gif"/></body></html>


输入输出样例1
输入:"div1"
输出:
HTML code
<div id="div1">        <div id="div2" style="background:Red;">                <div id="div3">                        <table id="table1">                                <tr>                                        <td>                                                <div id="div4" style="width:100px"></div>                                        </td>                                </tr>                        </table>                </div>        </div>        <div id="div5">                <a href="http://www.csdn.net">csdn</a>        </div></div>


输入输出样例2
输入:"div2"
输出:
HTML code
        <div id="div2" style="background:Red;">                <div id="div3">                        <table id="table1">                                <tr>                                        <td>                                                <div id="div4" style="width:100px"></div>                                        </td>                                </tr>                        </table>                </div>        </div>


输入输出样例3
输入:"div3"
输出:
HTML code
                <div id="div3">                        <table id="table1">                                <tr>                                        <td>                                                <div id="div4" style="width:100px"></div>                                        </td>                                </tr>                        </table>                </div>



输入输出样例4
输入:"table1"
输出:
HTML code
                        <table id="table1">                                <tr>                                        <td>                                                <div id="div4" style="width:100px"></div>                                        </td>                                </tr>                        </table> 



调试代码:
目前只实现没有嵌套的匹配--"div4"
C# code
using System;using System.Collections.Generic;using System.Text;using System.Text.RegularExpressions;namespace ConsoleApplication1{    class Program    {        static void Main(string[] args)        {            string html = @"<html><body><div id=""div1"">    <div id=""div2"" style=""background:Red;"">        <div id=""div3"">            <table id=""table1"">                <tr>                    <td>                        <div id=""div4"" style=""width:100px""></div>                    </td>                </tr>            </table>        </div>    </div>    <div id=""div5"">        <a href=""http://www.csdn.net"">csdn</a>    </div></div><img src=""http://www.csdn.net/Images/logo_csdn.gif""/></body></html>";            Console.WriteLine(html);            string[] idList = { "div1", "div2", "div3", "div4", "table1" };            /* TODO : 这里发挥 */            string pattern = @"<([a-z]+)[^>]*\bid=(""|'){0}\2[^>]*></\1>";             foreach (string id in idList)            {                Match match = Regex.Match(html, string.Format(pattern, id),                     RegexOptions.Singleline | RegexOptions.IgnoreCase);                Console.WriteLine("--------begin {0}--------", id);                if (match.Success)                    Console.WriteLine(match.Value);                else                    Console.WriteLine("o(╯□╰)o");                Console.WriteLine("--------end {0}--------", id);            }            Console.ReadKey();        }    }}


输出
--------begin div1--------
o(╯□╰)o
--------end div1--------
--------begin div2--------
o(╯□╰)o
--------end div2--------
--------begin div3--------
o(╯□╰)o
--------end div3--------
--------begin div4--------
<div id="div4" style="width:100px"></div>
--------end div4--------
--------begin table1--------
o(╯□╰)o
--------end table1--------


[解决办法]
先占座,后干活
[解决办法]
高手
  向你学习
[解决办法]
这个.....觉得正则不太适合搞这种事情.
[解决办法]
留脚印
[解决办法]
string pattern = @"(<([a-z]+)[^>]*\bid=(""|'){0}\3[^>]*>)(?<tag>).*(</\2>)(?<-tag>)";
[解决办法]
这不就相当于是xml里面的,通过一个标签得到它里面的所有内容嘛!
不知道理解的对不对,以后还请大家多多指教!
[解决办法]

document.getelementByid("asd").innerHTML不行吗

或用jquery的 $(#fg).appen(..)
[解决办法]
UP
当成XML来搞得了
[解决办法]
清洁工大侠也研究正则?

应该要用到平衡组。


可能还要考虑这种情况: 
<img id="img1" src="images/ok.gif" />

并且 id='img1' 或 id=img1 ,在浏览器中似乎都能正常工作,如果也要考虑这些情形,就更麻烦了。

[解决办法]
o(╯□╰)o 

对正则还没有研究得这么深... 平衡组都没有听说过 - -

要是我的话宁可自己分析标签,用stack来记录位置,顺便检查标签是否闭合。。。
[解决办法]
學習了
[解决办法]
<br> <hr> 写成 <br /> <hr /> 还好些,如果不写 /,就更不好判断闭合的情形了。

[解决办法]
Mark
[解决办法]
占位学习
[解决办法]
用正则处理貌似有困难
俺的正则还有待加强!
[解决办法]
太强了....留个脚印
[解决办法]
.
[解决办法]
我感觉用堆栈实现比较好。。。
还得研究一下。。。
[解决办法]
让俺先加个精再细细看~~
[解决办法]
我是过路的·············

[解决办法]
正则只会简单的呵呵。。。学习
[解决办法]
up
[解决办法]
路过,学习一下
[解决办法]
唉!我今天也要用到正则表达式,不过好像不会用似的,真失败
[解决办法]
完善一:增加了对以下标签类型的支持

HTML code
        <div id=div5>                <a href="http://www.csdn.net">csdn</a>        </div>
[解决办法]
正则只会用最简单的.
[解决办法]
lihai
[解决办法]
学习~
[解决办法]
在windows下开发桌面程序好像很少用到正则。
[解决办法]
学习……
[解决办法]
细节上优化了一下

C# code
string pattern = @"<([a-z]+)(?:(?!\bid\b)[^<>])*id=([""']?){0}\2[^>]*>(?>(?<o>)<\1[^>]*>|(?<-o>)</\1>|(?!</?\1).)*(?(o)(?!))</\1>";
[解决办法]
探讨
string pattern = @"<([a-z]+)(?:(?!id)[^<>])*id=([""']?){0}\2[^>]*>(?>(?<o><\1[^>]*>)|(?<-o></\1>)|(?:(?!</?\1).))*(?(o)(?!))</\1>";

[解决办法]
很强大 但是没看懂
老大能不能给讲一下阿 谢谢!!
[解决办法]
正则对我来说很难啊!!!!

[解决办法]
mark
[解决办法]

探讨
@"<([a-z]+)(?:(?!\bid\b)[^<>])*id=([""']?){0}\2[^>]*>(?>(?<o>)<\1[^>]*>|(?<-o>)</\1>|(?!</?\1).)*(?(o)(?!))</\1>";

[解决办法]
学习下
[解决办法]
顶顶
[解决办法]
帮顶
[解决办法]
up
[解决办法]
学习
[解决办法]
up
[解决办法]
探讨
string pattern = @"<([a-z]+)(?:(?!\bid\b)[^<>])*id=([""']?){0}\2[^>]*>(?>(?<o>)<\1[^>]*>|(?<-o>)</\1>|(?!</?\1).)*(?(o)(?!))</\1>";

[解决办法]
路过,学习学习
[解决办法]
还要考虑这种情形:
HTML code
<div id='div4' onclick="if(x>5){print('</div>')}"></div>
[解决办法]
HTML code
<img id='img1' src='ok.gif' />
[解决办法]
探讨
引用:
这个.....觉得正则不太适合搞这种事情.
是挺难的,,,如果有能减不少工作量。

[解决办法]
平衡组。。。不过似乎非常复杂。。。

是不是在程序里管理一个栈比较好?
[解决办法]
string pattern = @"( <([a-z]+)[^>]*\bid=(""|'){0}\3[^>]*>)(? <tag>).*( </\2>)(? <-tag>)";
[解决办法]
帮顶。
[解决办法]
学习
[解决办法]
Mark
[解决办法]
嵌套的问题确实不适合用正则去解,其实如果对性能要求过高的话,正则都是不合适的,在大多数情形下,正则的性能是比较差的。不过楼主这个问题对于学习正则来说是很典型的,涉及到许多正则当中少见但却是功能强大的地方。在这里斗胆将上面的正则表达式注释一下,希望对不熟悉正则的兄弟能够有所帮助。
<
([a-z]+)       (?# 匹配标签名称,若整个表达式匹配成功,会自动编组为 1。但这里仍然有疏漏,无法匹配类似于 h3 之类的标签)
[^>]* (?# 匹配标签和 id 间的任意字符)
id=
([""']?) (?# 匹配双/单引号或空,注意,在正则中,空也可以看作一项匹配,单纯的空匹配总会成功。若整个表达式匹配成功,编组为 2。)
{0} (?# 这个值在楼主的程序中会被具体的 id 名称代替)
\2           (?# 反向引用分组 2)
[^>]*>         (?# 匹配剩余的字符及尖括号)
(?> (?# 这是一个固化分组,表示本括号内后续的字符若匹配到了就不释放,以阻止回溯,可以提高效率)
(?<o>) (?# 空匹配,指定分组为 o。在这里的意思就是若发现后续的字符为分组 1 指定的标签,则压入一个位置进入堆栈,平衡组的开始)
<\1[^>]*>       (?# 匹配分组 1 类型的标签)
|
(?<-o>) (?# 平衡组出栈。在这里就是若发现后续的字符为分组 1 指定标签的闭合标签,则弹出最后入栈的分组 o)
</\1> (?# 匹配分组 1 指定标签的闭合标签)
|
(?!</?\1). (?# 否定预查,匹配不属于分组 1 指定标签及其闭合标签中的任意字符,同时匹配标签和闭合标签是通过 /? 来达成的)
)*           (?# 注意这个 * 号是针对整个括号的,所以它的作用范围是括号中的三个分支,这个括号的开头是一个固化分组)


(?(o)(?!))      (?# 这是一个条件测试,完整的形式形如 (?(group)(exp1)|(exp2)),或 group 匹配成功,则执行 exp1,否则执行 exp2)
(?# 因为 o 是一个平衡组,有入栈和出栈,若 o 全部出栈或根本未匹配到 o,则 (o) 为 false,正则引擎会继续匹配后续的表达式,即下面的 </\1>。若 o 未全部出栈,则 (o) 为 true,正则引擎会执行表达式 (?!),(?!) 总会导致匹配失败(因为空匹配总会成功,而对总会成功的匹配取反,则总会失败),从而导致正则引擎回溯,不去匹配最后的 </\1>。)
</\1> (?# 匹配分组 1 指定标签的闭合标签)

呵呵,个人的理解,有不当之外,敬请指正。
另外,个人认为正则的匹配能刚好达到要求最好,一是可以避免太复杂的表达式,难以看懂,二是效率问题。
[解决办法]
mark&&&
[解决办法]
头一次看见散400分的高人
[解决办法]
强大,就喜欢这些推荐的东西
[解决办法]
占位学习
[解决办法]
up
[解决办法]
很强大 但是没看懂 
老大能不能给讲一下阿 谢谢!!

[解决办法]
up
[解决办法]
写这么复杂的正则用自动机来进行词法分析,会不会更好一些
[解决办法]
呵呵,确实越考虑越复杂了

基本上正则就是具体问题具体分析,有什么样的需求就写什么样的正则,适用就好
一些不常见的规则,等真正有这种需求的时候再扩展吧,否则只会增加复杂度,降低效率和可维护性


效率一直是正则招人诟病的地方,但这种效率问题很大程度上是因为使用不当导致的

正则本身就是一种有穷状态机,对于一些需求,我们完全可以自己写状态机搞定,只不过抽象程度不会有正则这么高罢了
[解决办法]
mark,有时间再来看

热点排行