为啥用正则表达式解析 XML 是个坏主意? [关闭]

Posted

技术标签:

【中文标题】为啥用正则表达式解析 XML 是个坏主意? [关闭]【英文标题】:Why is it such a bad idea to parse XML with regex? [closed]为什么用正则表达式解析 XML 是个坏主意? [关闭] 【发布时间】:2012-01-24 12:16:54 【问题描述】:

我刚刚回顾了我之前的一篇文章,发现很多人建议我不要使用 Regex 来解析 xml。在那种情况下,xml 相对简单,并且 Regex 没有造成任何问题。我还解析了许多其他代码格式,所以为了统一起见,这是有道理的。但我很好奇这在其他情况下会如何造成问题。这只是“不要重新发明***”类型的问题吗?

【问题讨论】:

@Michael 正在等待链接。 您可以使用正则表达式从 XML 的小型、可预测、受限的 sn-ps 中提取信息位,没问题,但正则表达式不适用于解析整个 XML .这就像用圆头锤剥橘子一样。 这其实是一个很好的问题——最好在这里有一个明确的答案,只要有关于使用正则表达式解析 XML 的问题,都可以参考... 这个答案是关于解析 html,但仍然很有见地:***.com/questions/4231382/… 最佳答案是,***.com/a/1732454/135078(当心 Zalgo) 【参考方案1】:

真正的麻烦在于嵌套标签。嵌套标签很难用正则表达式处理。 balanced matching 可以做到这一点,但这仅适用于 .NET 和其他几种风格。但即使有平衡匹配的力量,位置不当的注释也可能会破坏正则表达式。

例如,这是一个很难解析的...

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

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

【讨论】:

你应该加入一些数字字符实体或 DTD 阻碍实体,以使其更难:-p。【参考方案2】:

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

如果您正在编写某种屏幕抓取工具,那么 99% 的成功率可能就足够了。对于大多数应用程序,它不是。

【讨论】:

正则表达式最初设计用于仅处理正则语言,但现代实现包括环视、反向引用,有时还包括平衡匹配。这使您可以冒险使用稍微复杂一点的语言……但对于像 XML 或 html 这样复杂的东西来说,这仍然不够。 我从未见过使用不会破坏某些内容的正则表达式解析 XML 的尝试(例如,在评论或 CDATA 部分中适当类似于 XML 的内容)。因此,使用正则表达式的唯一可接受的情况是您不介意它并不总是有效。 我同意。我只想提整个正则语言的事情,因为我曾经提出过同样的论点,后来才意识到我的错误。 孤立的自然语言几乎不够规则。即使是theoretically isolatable as "tag split" or "search term split"。以这两个为例:分别为r'[\s \t,]*("[^"]+"|\'[^\']+\'|[^ \t,]+)[ \t,]*'r'[\s \t]*([+-]?"[^"]+"|\'[^\']+\'|[^ \t]+)[ \t]*'。想到我为这些可憎的东西写了一个生成器,我嘴里吐了一点。 ;^P 而且这仍然(非常)脆弱的报价余额!【参考方案3】:

这已经在 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_ XPath 不是一种正则表达式。 XPath 是一种用于从 XML 文档中选择节点的查询语言。这与正则表达式无关。我怀疑你是否理解我的回答。问题不在于正则表达式不理解递归,而是:see regular-expression.info。问题是 (ht|x)ml 看起来如此不同,但结果相同。费了很大力气you can parse (ht|x)ml with regex,但是现有的解析器使用起来要简单得多 1.你指的是扩展。在 ComSci 的意义上,这些不是正则表达式。 2. 请阅读this 和背景资料。很容易制定不受正则表达式影响的 xml 文档。 3. XPath 和 Xsd 可以在实践中用于一些可以用正则表达式完成的事情,比如验证,以及在文档中查找内容。它们在......修辞意义上是相似的:-) @AK_,我说的是当今编程语言中使用的正则表达式,而不是乔姆斯基层次结构定义的常规语言。据我了解,自从引入反向引用以来,正则表达式不再是常规的,但这不是我的主题,而且这里 99,99% 的问题也不是主题。我完全同意你的第 2 点。这就是我一直想说的。 (也许我做得不好:-()

以上是关于为啥用正则表达式解析 XML 是个坏主意? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

您能否提供一些示例说明为啥使用正则表达式难以解析 XML 和 HTML? [关闭]

为啥 PHP 引用是个坏主意? zvals 和 Copy On Write 是怎么进来的? [关闭]

为啥调用 Process.killProcess(Process.myPid()) 是个坏主意?

为啥告诉您的服务器将 HTML 解析为 PHP 是一个坏主意? [关闭]

正则表达式 <img > 标签解析与 src、宽度、高度

为啥这个正则表达式调用 substcont 次数过多?