浅谈正则表达式匹配嵌套HTML标签
在.NET中我们可以很容易的使用Regex
类创建正则表达式对象,用于匹配、替换、筛选数据等,对于文本处理是非常有用的。
由于时间关系,本文不对正则表达式本身作介绍,而仅分析嵌套匹配的正则表达式作简单的分析。
一,匹配单一的嵌套标签
这种情况是比较简单的,因为只是匹配单一的嵌套标签,比如:
<div>我是一层<div> </div> <div class="test"> 我是二层div <div class="test"> 我是三层div</div></div> <div class="test"> 我是二层div</div> <div class="test"> 我是二层div</div> </div>
我们可以看出,在上面的HTML片断中只有div标签,那么正则表达式可以写成:
<div[^>]*>[^<>]* #匹配开始div以及非标签内容 ( ( (?'Open'<div[^>]*>)[^<>]*)+ #匹配开始div标签 ((?'-Open'</div>)[^<>]*)+ #匹配结束div标签 )* (?(Open)(?!)#如果堆栈上还有匹配组Open则匹配失败 ) </div> #匹配结尾div
在Regex Tester中测试结果:
如果我们在标签中添加<p></p><ul></ul>
等其它标签那么匹配就会失败了,不能匹配最外层的div标签。
二,修改的嵌套div正则,可包含其它标签
将HTML修改为:
<div>我是一层<div> </div><ul></ul> <div class="test"> 我是二层div <div class="test"> 我是三层div</div></div> <div class="test"> 我是二层div</div> <div class="test"> 我是二层div</div> </div>
正则表达式修改为:
<div[^>]*> #开始div标签 (?<tagcontent> #将div标签之间的所有内容捕获到组tagcontent中 (.|\n)*? #匹配任意字符或者换行符但是尽量少 ( ( (?'Open'<div[^>]*>) #匹配嵌套的div开始标签 (.|\n)*? #匹配开始div标签后的内容 )+ #匹配至少一个div开始标签,开始标签后面可以不跟任何内容也可以包含其它标签 ( (?'-Open'</div>) #匹配嵌套的div闭合标签 (.|\n)*? #匹配闭合div标签后的内容 )+ #匹配至少一个div闭合标签,闭合标签后面可以不跟任何内容也可以包含其它标签 )* #开始标签和闭合标签匹配0次或者以上的情况 (?(Open)(?!))#如果堆栈上还有组名为Open的项则匹配失败 ) </div> #结束div标签
在Regex Tester中测试结果为:
三,其它的相关说明
在二中,如果我们在html中多添加一个<div>标签或者在结束前添加一个</div>标签,那么整个html不是valid的xhtml,比如:
<div>我是一层<div><div> </div><ul></ul> <div class="test"> 我是二层div <div class="test"> 我是三层div</div></div> <div class="test"> 我是二层div</div> <div class="test"> 我是二层div</div> </div>
在上述中,如果将正则中(?(Open)(?!))
注释掉,那么会多一个匹配组Open
,且其内容为<div>
,如果不注释那么匹配组Open
的内容就会是一个位置而已,其Index为0,Length为0。
如果HTML为:
<div>我是一层<div> </div><ul></ul> <div class="test"> 我是二层div <div class="test"> 我是三层div</div></div> <div class="test"> 我是二层div</div> <div class="test"> 我是二层div</div></div> </div>
那么最后一个多余的</div>
不会匹配上。
有一点在参考文章中也有提到,这里再次强调下:
其中(?<-N>)
是表示释放之前捕获的N
分组。确切的语法是(?<N-M>)
即使用N
分组替换掉M
分组,如果N
分组没有指定或不存在,则释放M
分组。
参考文档
info Last modified by Raymond 3 years ago
copyright
This page is subject to Site terms.
comment Comments
No comments yet.