为什么使用正则表达式解析 XML 是个坏主意?[已结束]

Why is it such a bad idea to parse XML with regex? [closed]

提问人:yatakaka 提问时间:12/20/2011 更新时间:6/16/2012 访问量:29291

问:

我刚刚回顾了我之前发表的一篇文章,并注意到很多人建议我不使用正则表达式来解析 xml。在这种情况下,xml 相对简单,正则表达式不会造成任何问题。我还解析了许多其他代码格式,因此为了统一起见,这是有道理的。但我很好奇这在其他情况下会如何构成问题。这只是一个“不要重新发明轮子”类型的问题吗?

正则表达 XML 解析

评论

2赞 ApprenticeHacker 12/20/2011
@Michael等待链接。
4赞 BoltClock 12/20/2011
您可以使用正则表达式从小的、可预测的、受限制的 XML 片段中提取信息位,没问题,但正则表达式不是用于解析整个 XML。这就像用球锤削橘子一样。
2赞 Avi 12/20/2011
这实际上是一个很好的问题 - 在这里有一个明确的答案会很好,每当有关于使用正则表达式解析 XML 的问题时,都可以参考它......
2赞 martin clayton 12/20/2011
这个答案是关于解析 HTML 的,但仍然很有见地:stackoverflow.com/questions/4231382/......
3赞 Kelly S. French 1/13/2012
最好的答案是,stackoverflow.com/a/1732454/135078(当心 Zalgo)

答:

50赞 Steve Wortham 12/20/2011 #1

真正的麻烦是嵌套标签。嵌套标签很难用正则表达式处理。平衡匹配是可能的,但这仅在 .NET 中可用,也许还有其他几种风格。但是,即使具有平衡匹配的强大功能,一个位置不当的注释也可能会使正则表达式失去正则表达式。

例如,这是一个难以解析的问题......

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

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

评论

1赞 binki 10/30/2014
你应该加入一些数字字符实体或 DTD 违规实体,只是为了让它更难:-p。
9赞 stema 12/20/2011 #2

这在 SO 上已经讨论过很多次了。例如,参见

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

为什么不能使用正则表达式来解析 HTML/XML:通俗易懂的正式解释

只需点击屏幕右侧的链接即可获得更多答案。

我的结论:

很简单,因为正则表达式不是解析器,而是查找模式的工具。

如果你想在 (ht|x)ml 文件中找到一个非常具体的模式,请继续,正则表达式是完美的选择。

但是,如果你在每个 Foo 标签中搜索一些东西,这些东西可能具有不同顺序的属性,可以嵌套,可以格式错误(但仍然有效),那么请使用解析器,因为这不再是模式匹配。

评论

0赞 AK_ 10/23/2013
Xpath 有点像 XML 的正则表达式。问题在于正则表达式不理解递归。
2赞 stema 10/23/2013
@AK_XPath 不是一种正则表达式。XPath 是一种用于从 XML 文档中选择节点的查询语言。这与正则表达式无关。我怀疑你是否理解了我的答案。问题不在于正则表达式不理解递归,而是它们理解:参见 regular-expression.info。问题在于 (ht|x)ml 可能看起来如此不同,但结果相同。通过大量的努力,你可以用正则表达式解析(ht|x)ml,但现有的解析器使用起来要简单得多
0赞 AK_ 10/24/2013
1.您所指的是扩展。这些不是 ComSci 意义上的正则表达式。2. 请阅读本文和背景资料。制定一个不受正则表达式影响的 XML 文档很容易。3. XPath 和 Xsd ,在实践中可以用于一些可以用正则表达式完成的事情,比如验证,以及在文档中查找东西。它们在....修辞意义:-)
0赞 stema 10/24/2013
@AK_,我说的是当今编程语言中使用的正则表达式,而不是乔姆斯基层次结构定义的常规语言。据我了解,自从引入反向引用以来,正则表达式不再是常规的,但这不是我的主题,在这里 99,99% 的问题中,它也不是主题。我完全同意你的观点 2。这就是我一直想说的。(也许我做得不好:-( )
6赞 Michael Kay 12/21/2011 #3

XML 不是一种常规语言(这是一个技术术语),因此您永远无法使用正则表达式正确解析它。你可能在99%的时间里都成功了,但随后有人会找到一种方法来编写让你失望的XML。

如果你正在编写某种屏幕抓取工具,那么 99% 的成功率可能就足够了。对于大多数应用程序来说,事实并非如此。

评论

2赞 Steve Wortham 12/21/2011
正则表达式最初被设计为仅处理正则语言,但现代实现包括环绕、反向引用,有时还包括平衡匹配。这使您可以冒险使用稍微复杂的语言......但对于像XML或html这样复杂的东西来说,这仍然不够。
3赞 Michael Kay 12/24/2011
我从未见过尝试使用不会破坏某些内容的正则表达式来解析 XML(例如,在注释或 CDATA 部分中适当地类似于 XML 的东西)。因此,使用正则表达式的唯一可接受的情况是,如果它并不总是有效,您不介意。
0赞 Steve Wortham 12/24/2011
我同意。我只想提一下整个常规语言的事情,因为我曾经提出过同样的论点,后来意识到我的错误。
0赞 amcgregor 6/17/2019
孤立的自然语言勉强够规律。即使是在理论上可以隔离的东西,如“标签拆分”或“搜索词拆分”。以这两个为例:和分别。想到我为这些可憎的东西写了一个生成器,我有点吐了。8^3而这对于报价余额来说仍然(极其)脆弱!r'[\s \t,]*("[^"]+"|\'[^\']+\'|[^ \t,]+)[ \t,]*'r'[\s \t]*([+-]?"[^"]+"|\'[^\']+\'|[^ \t]+)[ \t]*'