这类嵌套正则如何写?通过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(); } }}
[解决办法]
先占座,后干活
[解决办法]
高手
向你学习
[解决办法]
这个.....觉得正则不太适合搞这种事情.
[解决办法]
留脚印
[解决办法]
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>";
[解决办法]
[解决办法]
很强大 但是没看懂
老大能不能给讲一下阿 谢谢!!
[解决办法]
正则对我来说很难啊!!!!
[解决办法]
mark
[解决办法]
[解决办法]
学习下
[解决办法]
顶顶
[解决办法]
帮顶
[解决办法]
up
[解决办法]
学习
[解决办法]
up
[解决办法]
[解决办法]
路过,学习学习
[解决办法]
还要考虑这种情形:
- 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,有时间再来看