在网上搜了好久也没找到完美的解决方案。不过,我们可以实现有限级Html嵌套标签匹配。思路相对于无限级来说就简单了好多,不需要那么多高级的特性。
示例:
<div><BR> <div><BR> <a href='#'>Top</a><BR> <a href='https://wordpress.org/'>WordPress</a><BR> <div><BR> Copyright © 2009 简单生活 —— Kevin Yang的博客<BR> </div><BR> <div><BR> Theme by <a href='https://www.neoease.com/'>mg12</a>. Valid <a href='http://validator.w3.org/check?uri=referer'>XHTML 1.1</a><BR> and <a href='https://jigsaw.w3.org/css-validator/'>CSS 3</a>.<BR> </div><BR> </div><BR></div>
在上面这个示例中,我们打算匹配id为footer的这个嵌套div,而且假设我们预先知道footer这个div里面最多只会嵌套一级div。更多级的情况我们一会儿再讲。
footer的开始和结束标签匹配很简单:
<div [^>]*id='footer'[^>]*>......(这里的省略号是一会要填写的)</div>
夹在开始和结束标签之间的内容无非有两种情况:
内容A: div标签,并且此div内无嵌套div
内容B: 任意其他内容
然后就是这两种内容的不断重复而已。正则表示如下:
(<div[^>]*>.*?</div>|.)*?
注意最后面的问号必须要加上,否则由于正则的贪婪匹配特性,footer的闭合标签会匹配失误。
OK了,匹配最多嵌套一级div的正则表达式如下:
<div [^>]*id='footer'[^>]*>(<div[^>]*>.*?</div>|.)*?</div>
那么如果footer标签里头最多会嵌套两级div的话怎么办呢?
其实也不难,我们只需要把上面的“内容A”部分中的点号稍作替换即可。修改如下:
<div [^>]*id='footer'[^>]*>(<div[^>]*>(<div[^>]*>.*?</div>|.)*?</div>|.)*?</div>
到这里你可能就知道,如果要匹配最多嵌套三级div的话,正则应该怎么写了:
<div [^>]*id='footer'[^>]*>(<div[^>]*>(<div[^>]*>(<div[^>]*>.*?</div>|.)*?</div>|.)*?</div>|.)*?</div>
所以实际上,只要你的html结构不是特别复杂的话,也就是说嵌套不会很深的话,那么你完全可以使用这种方式来匹配嵌套html标签。
这个正则在Java和Javascript中都可以使用,因为它没有用到任何高级特性。
接着补充
查找所有的TD区域(最短):
<td\s*.*>\s*.*<\/td>
查找所有的TR:
<tr.*(?=>)(.|\n)*?</tr>
查找所有的TD:
<td.*(?=>)(.|\n)*?</td>
正则表达式匹配Html标签
例1.
以下是一段Html代码
<table boder="0"> <tr> <td> <p>其它内容...</p> </td> </tr> </table> <table> <tr> <td> <p>典经HTML正则表达式!</p> </td> </tr> </table> <table boder="0"> <tr> <td> <p>其它内容...</p> </td> </tr> </table>
正则表过式:<table.*(?=headline)
说明:正则表达式匹配表格开始标记,能够返回开始标记直至 “headline”之间的所有内容(换行除外);
就是以上红色标示出来的部分。
原理:
<table //匹配的开始部分
.* //除换行外的所有字符
(?=headline) //零宽度正预测先行断言,匹配以 headline 结尾的单词的前面部分(除了 headline 以外的部分)
例2.
<table boder="0"> <tr> <td> <p>其它内容...</p> </td> </tr> </table> <table> <tr> <td> <p>典经HTML正则表达式!</p> </td> </tr> </table> <table boder="0"> <tr> <td> <p>其它内容...</p> </td> </tr> </table>