似乎在stackoverflow上的每个问题中,提问者使用regex从HTML中获取一些信息,将不可避免地有一个“答案”,说不要使用regex解析HTML。

为什么不呢?我知道有一些所谓的“真正的”HTML解析器,比如Beautiful Soup,我相信它们是强大而有用的,但如果您只是在做一些简单、快速或简单的事情,那么当一些正则表达式语句就可以很好地工作时,为什么要麻烦使用如此复杂的东西呢?

此外,是否只是因为我不理解正则表达式的某些基本原理,才使得它们在解析中成为一个糟糕的选择?


当前回答

在某些情况下,使用正则表达式解析HTML中的某些信息是正确的——这在很大程度上取决于具体情况。

上面的共识是,总的来说,这是一个坏主意。然而,如果HTML结构是已知的(并且不太可能改变),那么它仍然是一种有效的方法。

其他回答

对于快速´n´dirty regexp就可以了。但是要知道的基本问题是,不可能构造一个正确解析HTML的regexp。

原因是regexp不能处理任意嵌套的表达式。参见正则表达式能否用于匹配嵌套模式?

就解析而言,正则表达式在“词法分析”(lexer)阶段很有用,在这个阶段,输入被分解成标记。它在实际的“构建解析树”阶段用处不大。

对于HTML解析器,我希望它只接受格式良好的HTML,而这需要正则表达式所不能做到的功能(它们不能“计数”并确保给定数量的开始元素与相同数量的结束元素相平衡)。

正则表达式并不是为处理嵌套的标记结构而设计的,要处理真正HTML中可能出现的所有边缘情况,往好里说是复杂的(往坏里说是不可能的)。

“这要看情况”。由于这里给出的所有原因,正则表达式不能也不能准确地解析HTML,这是事实。但是,如果错误的后果(比如不处理嵌套标记)很小,如果正则表达式在您的环境中非常方便(比如在入侵Perl时),那么就继续。

假设您正在解析链接到您站点的网页——也许您是通过谷歌链接搜索找到它们的——并且您想要一种快速方法来大致了解链接周围的上下文。您试图运行一个小报告,可能会提醒您链接垃圾邮件,诸如此类。

在这种情况下,对某些文档进行错误解析并不是什么大问题。除了你自己,没有人会发现错误,如果你足够幸运,你可以单独跟进。

我想我是说这是一种权衡。有时,实现或使用正确的解析器(尽管很简单)可能不值得麻烦,如果准确性不是至关重要的话。

小心你的假设。例如,如果您试图解析将公开显示的内容,我可以想到regexp快捷方式可能适得其反的几种情况。

我相信答案就在计算理论中。对于使用正则表达式解析的语言,根据定义必须是“regular”(链接)。HTML不是常规语言,因为它不符合常规语言的许多标准(与HTML代码中固有的多层嵌套有很大关系)。如果你对计算理论感兴趣,我推荐这本书。