为了账号安全,请及时绑定邮箱和手机立即绑定

您能否举例说明为什么难以用正则表达式解析XML和HTML?

/ 猿问

您能否举例说明为什么难以用正则表达式解析XML和HTML?

您能否举例说明为什么难以用正则表达式解析XML和HTML?

一个错误我看到人们做,并再次试图解析XML或HTML用正则表达式。以下是解析XML和HTML很难的几个原因:

人们希望将文件视为一系列行,但这是有效的:

<tagattr="5"/>

人们希望将<或<tag视为标记的开头,但是这样的东西存在于野外:

<img src="imgtag.gif" alt="<img>" />

人们通常希望将起始标记与结束标记匹配,但XML和HTML允许标记包含自身(传统的正则表达式根本无法处理):

<span id="outer"><span id="inner">foo</span></span>

人们通常希望匹配文档的内容(例如着名的“查找给定页面上的所有电话号码”问题),但数据可能会被标记(即使在查看时看起来是正常的):

<span class="phonenum">(<span class="area code">703</span>)<span class="prefix">348</span>-<span class="linenum">3020</span></span>

评论可能包含格式不正确或不完整的标记:

<a href="foo">foo</a><!-- FIXME:
    <a href="
--><a href="bar">bar</a>

你还知道其他什么问题?


查看完整描述

3 回答

?
慕标5265247

其实

<img src="imgtag.gif" alt="<img>" />

是无效的HTML,也不是有效的XML。

它不是有效的XML,因为'<'和'>'在属性字符串中不是有效字符。它们需要使用相应的XML实体进行转义&lt; 和&gt;

它不是有效的HTML,因为HTML中不允许使用简短的结束表单(但在XML和XHTML中是正确的)。根据HTML 4.01规范,'img'标记也是隐式封闭标记。这意味着手动关闭它实际上是错误的,相当于两次关闭任何其他标签。

HTML中的正确版本是

<img src="imgtag.gif" alt="&lt;img&gt;">

XHTML和XML中的正确版本是

<img src="imgtag.gif" alt="&lt;img&gt;"/>

您提供的以下示例也无效

<
tag
attr="5"
/>

这也不是有效的HTML或XML。标签的名称必须位于“<”后面,尽管属性和结束“>”可能位于他们想要的任何位置。所以有效的XML实际上就是这样

<tagattr="5"/>

这是另一个更有趣的一个:你实际上可以选择使用“或”作为你的属性引用字符

<img src="image.gif" alt='This is single quoted AND valid!'>

发布的所有其他原因都是正确的,但解析HTML的最大问题是人们通常无法正确理解所有语法规则。您的浏览器将您的tagsoup解释为HTML这一事实并不意味着您实际上已经编写了有效的HTML。

编辑:甚至stackoverflow.com也同意我关于有效和无效的定义。您的无效XML / HTML未突出显示,而我的更正版本是。

基本上,XML不能用regexp解析。但也没有理由这样做。每种语言都有许多XML解析器。您可以选择SAX解析器,DOM解析器和Pull解析器。所有这些都保证比使用正则表达式解析要快得多,然后您可以在生成的DOM树上使用XPath或XSLT等酷技术。

因此,我的回答是:不仅难以用正则表达式解析XML,而且这也是一个坏主意。只需使用数百万个现有XML解析器中的一个,并利用XML的所有高级功能。

HTML甚至难以自己解析。首先,法律语法有许多你可能不知道的微妙之处,其次,野外的HTML只是一堆巨大的(你得到我的漂移)。有很多松散的解析器库可以很好地处理像标签汤这样的HTML,只需使用它们。


查看完整回答
反对 回复 2019-05-23
?
呼啦一阵风

我写了一篇关于这个主题的完整博客文章:正则表达式限制

问题的关键在于HTML和XML是递归结构,需要计数机制才能正确解析。真正的正则表达式无法计数。您必须具有无上下文语法才能计算。

前一段有一点需要注意。某些正则表达式实现现在支持递归的想法。但是,一旦开始将recursion添加到正则表达式中,您实际上是在扩展边界并且应该考虑使用解析器。


查看完整回答
反对 回复 2019-05-23

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信