什么时候使用HTML的正则表达式是明智的?

时间:2009-11-29 18:13:01

标签: html regex parsing

虽然regexp不是完全解析HTML文档的正确工具,但我发现很多人盲目地忽略了有关regexp的任何问题,如果他们在提议的文本中看到一个HTML标签那么多。

由于我们看到很多regexp 而不是的例子是正确的工具,我在此问你的意见:简单模式匹配比使用完整解析更好的解决方案是什么情况发动机?

10 个答案:

答案 0 :(得分:11)

如果您想要使用正则表达式解析的HTML集合已知符合某种模式。例如如果您知道没有注释掉的HTML或复杂的场景等。

e.g。我经常宣传你不应该使用regexp进行HTML,但是如果我有一套我熟悉的HTML,很简单并且我可以很容易地检查后操作,那么我对使用正则表达式没有任何疑虑这一点。

答案 1 :(得分:4)

我认为这里最好的答案是:正则表达式是正确的工具,除非它们不是。

我认为如果您能够使用正则表达式干净利落地解决问题,那就去吧。但是我看到太多的正则表达式黑客攻击,因为程序员/网页设计师只是懒惰。

正则表达式是强大的,是程序员可以学习的最好的工具之一,但您还需要学习何时使用以及何时使用不同的东西。

答案 2 :(得分:3)

Jeff Atwood在题为Programming Is Hard Let's Go ShoppingParsing HTML The Cthulhu Way的博客文章中对此进行了广泛讨论。

  

“所以,是的,一般来说,在解析HTML时使用正则表达式是一个坏主意。我们绝对应该教新手开发人员。尽管这显然是一项无休止的工作。但我们也应该教他们解析HTML与处理一些字符串的简单方法之间存在非常真实的区别。如何判断哪种方法适用于手头的任务。“

在上述帖子中查找更多详细信息。

答案 3 :(得分:2)

显然,在最简单的情况下,如

<a>Test</a>

你可能与正则表达式相处得很好。但即便如此,一个完全有效的HTML标签可能有很多不同的类型:

< A > Test</a>                // match
< a href="test">   Test</a>   // match
< A TEST="test"/>             // no match
< a href="test<">Test</A>     // invalid input - catch that with a regex!

可靠地捕获它们的正则表达式变得巨大。基于DOM的解析器将对其进行解析,如果失败则会给出正确的错误消息,并提供稳定的结果。

答案 4 :(得分:1)

值得记住的一件事是,使用正则表达式处理HTML有两个主要的反对意见。一个来源与垃圾HTML的可能性不可预测的错误概率有关。这本身就是在使用正则表达式处理HTML处理时持怀疑态度的正当理由,并从一开始就抛弃了大量用例。问题是这个来源经常被用来“用洗澡水甩掉婴儿”,并且经常与第二个主要反对来源混淆(通常两者都没有说明),即使它们完全不相关。

另一个主要的反对来源与HTML语言的复杂性有关,超出了一些理想化的“正则表达式”理论概念,这种概念过于笼统,不适用于许多用例 - 但通常全面适用。反对意见如下:

  1. 真理:正则表达式处理常规语法。
  2. 真理:HTML不是常规语法。
  3. 无法使用正则表达式处理HTML。
  4. 我认为很多人真的只是从表面看待这些真理,而不考虑他们的意思。 Bill Karwin在这里的另一个答案中提到了一些HTML不是常规语法的情况,但是当上下文是具有非常规特征的“正则表达式”引擎(如后向引用,甚至是递归)时,这个论点就会崩溃。这些功能解决了许多“非常规语法”异议,但在格式错误的文档上可能仍会失败。

    这种区别很少被提及,并且很少指出大多数现代“常规”表达库具有远远超出常规语言处理的能力。我认为在评估处理某些HTML的适当工具的“常规”表达式时,这些都是需要考虑的重要事项。

答案 5 :(得分:1)

如果您可以保证您需要匹配的模式位于单个 HTML标记内,那么您可以创建一个正则表达式来匹配它。

换句话说,当您需要表达式来查找匹配的标记/结束标记时当您需要匹配的内容可能包含嵌套标记,注释,CDATA时部分等。

答案 6 :(得分:1)

如果您使用的信息具有常规语法,那么正则表达式很棒。 HTML没有常规语法,因此事情更复杂。

如果您绝对100%知道您正在寻找什么样的东西,那么正则表达式是合适的 - 替换:

<tag>Info</tag>

<tag>Dave</tag>

在一个你完全控制的文档中,有意义,但现实生活中的HTML不是这样的。

答案 7 :(得分:1)

当你知道自己在做什么时!

答案 8 :(得分:0)

我刚刚发现了regexp击败html解析器的一个例子。我需要从一个长页面(8231行,400kb)中提取一些信息,我首先尝试使用simple_html_dom。由于this question中报告的问题导致我陷入困境,我选择了另一种方法,我意识到我实际上只需要该文件的前416行中包含的信息(约占总数的4%)并加载整个DOM进入内存看起来像是一种巨大的资源浪费。

现在我仍然不知道为什么simplehtmldom会失败,所以我无法真正比​​较两种解决方案的性能,但正则表达式只能根据需要加载尽可能多的行(直到{ {1}}我对此感兴趣并且不再感兴趣。并且非常快。

答案 9 :(得分:0)

当你解析你可以控制的HTML或者你正在为一个特定的HTML页面编写解析器时,你可以使用regexp。在尝试构建通用解析器时,不应使用regexp。