为什么使用正则表达式解析XML是一个坏主意?

30

我刚刚回顾了之前发布的帖子,注意到有许多人建议我不要使用正则表达式来解析XML。在那种情况下,XML相对简单,使用正则表达式也没有问题。但是我还要解析其他一些代码格式,为了统一起见,使用正则表达式是有意义的。但我很好奇它在其他情况下可能会产生什么问题。这只是一种“不要重复造轮子”的问题吗?


2
@Michael 等待链接。 - ApprenticeHacker
4
您可以使用正则表达式从小且可预测的XML片段中提取信息,没有问题,但是正则表达式并不适用于整体解析XML。这就像用圆头锤子去剥橙子一样。 - BoltClock
2
这实际上是一个很好的问题 - 有一个明确的答案会很好,每当涉及使用正则表达式解析 XML 时都可以参考它... - Avi
2
这个答案是关于解析HTML的,但仍然很有见地:https://dev59.com/2W855IYBdhLWcg3woV7M#4234491 - martin clayton
3
最佳答案是 https://dev59.com/X3I-5IYBdhLWcg3wq6do#1732454(注意 Zalgo)。 - Kelly S. French
显示剩余2条评论
3个回答

50

真正的麻烦在于嵌套标签。嵌套标签很难用正则表达式处理。虽然使用平衡匹配可能是可行的,但这只适用于.NET和其他几个版本。但即使使用平衡匹配的强大功能,一个放置不当的注释也可能扰乱正则表达式。

例如,这是一个棘手的解析示例...

<div>
    <div id="parse-this">
        <!-- oops</div> -->
        try to get this value with regex
    </div>
</div>

你可能需要花费数小时来使用正则表达式解决这样的边缘情况,也许能找到一个解决方案。但实际上,当有专门处理XML、XHTML和HTML的解析器可以更可靠和高效地完成工作时,这是没有意义的。


1
你应该加入一些数字字符实体或DTD定义的实体,以使它更难 :-p。 - binki

9
这个问题在SO上已经讨论了很多次。请参考以下链接:Can you provide some examples of why it is hard to parse XML and HTML with a regex?Why it's not possible to use regex to parse HTML/XML: a formal explanation in layman's terms。您可以在屏幕右侧的链接中找到更多答案。
我的结论是:使用正则表达式是因为它不是一个解析器,而是一种查找模式的工具。如果您想在(ht|x)ml文件中查找非常特定的模式,请继续使用正则表达式。但是,如果您正在搜索每个Foo标签中的内容,并且这些标签可能具有不同顺序的属性,可能嵌套,可能格式不正确(但仍然有效),那么请使用解析器,因为这不再是模式匹配。

XPath是XML的一种类似于正则表达式的语法。问题在于正则表达式不理解递归。 - AK_
2
@AK_ XPath不是正则表达式的一种。*XPath是一种用于从XML文档中选择节点的查询语言*。这与正则表达式无关。我怀疑你是否理解了我的回答。问题不在于正则表达式不理解递归,它们确实可以:请参见regular-expression.info。问题在于(ht|x)ml可能看起来非常不同,但结果相同。虽然可以通过大量努力使用正则表达式解析(ht|x)ml,但现有的解析器更简单易用。 - stema
  1. 你所指的是扩展。从计算机科学的角度来看,这些不是正则表达式。
  2. 请阅读此文以及相关背景知识。很容易构建一个无法被正则表达式匹配的XML文档。
  3. XPath和Xsd在实践中可以用于一些正则表达式能做到的事情,比如验证和查找文档中的内容。它们在修辞意义上相似 :-)
- AK_
@AK_,我在谈论当今编程语言中使用的正则表达式,而不是乔姆斯基层次定义的常规语言。据我所知,自从引入反向引用以来,正则表达式已经不再是正则的了,但这不是我的话题,在99.99%的问题中,这也不是话题。我完全同意你的第二点。这就是我一直想说的。 (也许我没有做好 :-() - stema

6

XML不是一种正则语言(这是一个技术术语),因此您永远无法使用正则表达式正确解析它。您可能成功99%的时间,但随后会有人发现编写XML的方法使您失效。

如果您正在编写某种屏幕抓取程序,则99%的成功率可能足够。但对于大多数应用程序来说,这是不够的。


2
正则表达式最初只设计用于处理正则语言,但现代实现包括环视、反向引用和有时候的平衡匹配。这使得您可以涉足稍微复杂一些的语言……但对于像 XML 或 HTML 这样复杂的内容仍然不够。 - Steve Wortham
3
我从未见过使用正则表达式解析XML,并且不会在某些内容(例如注释或CDATA部分内部的类似XML的内容)上出问题的尝试。因此,仅当您不介意它无法始终正常工作时,才可以使用正则表达式。 - Michael Kay
我同意。我只是想提一下整个正则语言的事情,因为我曾经做过同样的论证,后来意识到了我的错误。 - Steve Wortham
孤立的自然语言几乎不够规则。即使在理论上可以隔离的“标签拆分”或“搜索术语拆分”等内容上也是如此。以这两个为例:r'[\s \t,]*("[^"]+"|\'[^\']+\'|[^ \t,]+)[ \t,]*'r'[\s \t]*([+-]?"[^"]+"|\'[^\']+\'|[^ \t]+)[ \t]*'。想到我写了这些可怕的生成器,我就有点反胃。; ^P 而且这仍然(极其)容易受到引号平衡的影响! - amcgregor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接