由于时间关系,本文不对正则表达式本身作介绍,而仅分析嵌套匹配的正则表达式作简单的分析,大家可以参考一下两篇文章:
一,匹配单一的嵌套标签
这种情况是比较简单的,因为只是匹配单一的嵌套标签,比如
我是一层
我是二层div
我是三层div
我们可以看出,在上面的HTML片断中只有div标签,那么正则表达式可以写成:
]*>[^<]* #匹配开始div以及非标签内容
(
((?'Open'
(
((?'Open'
]*>)[^<]*)+ #匹配开始div标签
((?'-Open'
((?'-Open'
)[^<]*)+ #匹配结束div标签
)*
(?(Open)(?!)#如果堆栈上还有匹配组Open则匹配失败
#匹配结尾div
在Regex Tester中测试结果:
如果我们在标签中添加
等其它标签那么匹配就会失败了,不能匹配最外层的div标签。
二,修改的嵌套div正则,可包含其它标签
将HTML修改为:
我是一层
我是二层div
我是三层div
我是span呀
-
我是ul呀
正则表达式修改为:
]*> #开始div标签
[sS]*? #匹配任意字符或者换行符但是尽量少
(
(
(?'Open'
[sS]*? #匹配任意字符或者换行符但是尽量少
(
(
(?'Open'
]*>) #匹配嵌套的div开始标签
[sS]*? #匹配开始div标签后的内容
)+ #匹配至少一个div开始标签,开始标签后面可以不跟任何内容也可以包含其它标签
(
(?'-Open') #匹配嵌套的div闭合标签
[sS]*? #匹配闭合div标签后的内容
)+ #匹配至少一个div闭合标签,闭合标签后面可以不跟任何内容也可以包含其它标签
)* #开始标签和闭合标签匹配0次或者以上的情况
(?(Open)(?!))#如果堆栈上还有组名为Open的项则匹配失败
#结束div标签
[sS]*? #匹配开始div标签后的内容
)+ #匹配至少一个div开始标签,开始标签后面可以不跟任何内容也可以包含其它标签
(
(?'-Open') #匹配嵌套的div闭合标签
[sS]*? #匹配闭合div标签后的内容
)+ #匹配至少一个div闭合标签,闭合标签后面可以不跟任何内容也可以包含其它标签
)* #开始标签和闭合标签匹配0次或者以上的情况
(?(Open)(?!))#如果堆栈上还有组名为Open的项则匹配失败
#结束div标签
]*>[sS]*?(((?'open'
]*>)[sS]*?)+((?'-open'
)[sS]*?)+)*(?(open)(?!))
在Regex Tester中测试结果为:
三,其它的相关说明
在二中,如果我们在html中多添加一个
标签或者在结束前添加一个
标签,那么整个html不是valid的xhtml,比如:
我是一层
我是div
我是div
在上述中,如果将正则中(?(Open)(?!))注释掉,那么会多一个匹配组Open,且其内容为
,如果不注释那么匹配组Open的内容就会是一个位置而已,其Index为0,Length为0。
有一点在参考文章中也有提到,这里再次强调下:
其中(?<-N>)是表示释放之前捕获的N分组。确切的语法是(?