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

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

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


当前回答

(来自http://htmlparsing.com/regexes)

假设您有一个HTML文件,您试图从中提取url < img >标签。

<img src="http://example.com/whatever.jpg">

所以你可以用Perl写一个这样的正则表达式:

if ( $html =~ /<img src="(.+)"/ ) {
    $url = $1;
}

在本例中,$url确实包含 http://example.com/whatever.jpg。但是当 你会得到这样的HTML:

<img src='http://example.com/whatever.jpg'>

or

<img src=http://example.com/whatever.jpg>

or

<img border=0 src="http://example.com/whatever.jpg">

or

<img
    src="http://example.com/whatever.jpg">

否则你就会得到假阳性

<!-- // commented out
<img src="http://example.com/outdated.png">
-->

它看起来很简单,对于一个单一的、不变的文件来说可能很简单,但是对于任意HTML数据,正则表达式只会让你将来头疼。

其他回答

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

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

问题是,大多数用户问的问题都与HTML和正则表达式有关,因为他们找不到自己的正则表达式。然后,必须考虑使用DOM或SAX解析器或类似的东西是否会更容易一些。它们是为处理类似xml的文档结构而优化和构造的。

当然,有些问题可以用正则表达式轻松解决。但重点在于容易。

如果您只想找到所有看起来像http://.../的url,那么使用regexp是没问题的。但是如果你想要找到a- element中所有具有'mylink'类的url,你可能最好使用合适的解析器。

请记住,虽然HTML本身不是规则的,但您正在查看的页面的某些部分可能是规则的。

例如,<form>标签被嵌套是一个错误;如果网页正常工作,那么使用正则表达式获取<form>将是完全合理的。

I recently did some web scraping using only Selenium and regular expressions. I got away with it because the data I wanted was put in a <form>, and put in a simple table format (so I could even count on <table>, <tr> and <td> to be non-nested--which is actually highly unusual). In some degree, regular expressions were even almost necessary, because some of the structure I needed to access was delimited by comments. (Beautiful Soup can give you comments, but it would have been difficult to grab <!-- BEGIN --> and <!-- END --> blocks using Beautiful Soup.)

但是,如果我不得不担心嵌套表,那么我的方法根本就行不通!我就只能靠《美丽汤》了。但是,即使这样,有时也可以使用正则表达式获取所需的块,然后从那里展开。

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

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