惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threat Research - Cisco Blogs
V2EX - 技术
V2EX - 技术
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
Recorded Future
Recorded Future
S
Schneier on Security
I
InfoQ
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The GitHub Blog
The GitHub Blog
S
Security @ Cisco Blogs
O
OpenAI News
W
WeLiveSecurity
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
人人都是产品经理
人人都是产品经理
Cloudbric
Cloudbric
The Last Watchdog
The Last Watchdog
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
NISL@THU
NISL@THU
T
Tailwind CSS Blog
V
Visual Studio Blog
PCI Perspectives
PCI Perspectives
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
D
DataBreaches.Net
B
Blog RSS Feed
N
News and Events Feed by Topic
N
News and Events Feed by Topic
H
Heimdal Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
腾讯CDC
Latest news
Latest news
V
Vulnerabilities – Threatpost
Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
V
V2EX
aimingoo的专栏
aimingoo的专栏
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Register - Security
The Register - Security
Help Net Security
Help Net Security

博客园 - KK2038

诚招.Net研发人员 VS编译时自动引用Debug|Release版本的dll 盘点国内外不同特色的Web流量分析工具 IE无法设置短域名下Cookie 使用XamlReader.Load构建配置型自定义控件 几个有趣的Javascript Hack Hilo: Windows 7下C++应用程序开发实战演练 晒晒自己电脑里的常用工具 Visual Studio编辑器一次缩进/反缩进4个空格 Win7访问远程桌面最大化同时让任务栏可见 Sql Tips——Update语句也使用表别名(Table Alias) 关于字符编码,你所需要知道的 Silverlight 4+RIA Services--搜索引擎优化(SEO) 64位系统下IIS7 ISAPI处理器加载失败 为什么IIS7/7.5的Gzip不起作用 SSIS调用存储过程失败 当Google Analytics、Firefox和IIS走到了一起... VS2010的UI设计失误 微软技术社区精英计划——你也来加入吧
Java/Js如何使用正则表达式匹配嵌套Html标签
KK2038 · 2010-07-30 · via 博客园 - KK2038

以前写过一篇文章讲解如何使用正则表达式完美解决Html嵌套标签的匹配问题(使用正则表达式匹配嵌套Html标签),但是里头用到了平衡组这样的高级特性,貌似只有DotNet还有Perl正则引擎支持,因此通用性不高。有朋友留言说Java直接使用的话会报错。我后来查了一下,发现Java正则引擎支持的特性相对比较少。在1.6版本中不能使用命名组(貌似1.7的时候开始支持了),否则会报以下错误,更别说平衡组了。因此感觉要实现无限级的嵌套匹配不大现实。

java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index XX

在网上搜了好久也没找到完美的解决方案。不过,我们可以实现有限级Html嵌套标签匹配。思路相对于无限级来说就简单了好多,不需要那么多高级的特性。

示例:

<div id='container'>
<div style='background-color:gray;' id='footer'>
<a id='gotop' href='#' onclick='MGJS.goTop();return false;'>Top</a>
<a id='powered' href='http://wordpress.org/'>WordPress</a>
<div id='copyright'>
Copyright &copy; 2009 简单生活 —— Kevin Yang的博客
</div>
<div id='themeinfo'>
Theme by <a href='http://www.neoease.com/'>mg12</a>. Valid <a href='http://validator.w3.org/check?uri=referer'>XHTML 1.1</a>
and <a href='http://jigsaw.w3.org/css-validator/'>CSS 3</a>.
</div>
</div>
</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中都可以使用,因为它没有用到任何高级特性。

——Kevin Yang