所以其他人已经对大多数这些东西给出了简要定义,但我真的不认为它们涵盖了为什么正则表达式是什么样子。
有一些很好的资源可以了解有限状态机是什么,简单来说,计算机科学中的一篇重要论文证明了正则表达式的基本语法(标准的那种,由grep使用,而不是扩展的那种,比如PCRE)总是可以转化为一个有限状态机,意味着你总是处于一个“盒子”中,并且有限的方法可以移动到下一个盒子。简而言之,你只需查看当前字符,就可以始终知道下一步该做什么。(是的,即使是像“至少匹配4次,但不超过5次”这样的情况,你仍然可以创建这样的机器)(值得注意的是,我在这里描述的机器在技术上只是有限状态机的一种子类型,但它可以实现任何其他子类型,所以...)
这很棒,因为你可以非常高效地评估这样的机器,即使对于大输入也是如此。研究这些问题(当我喂给算法的东西数量变大时,我的算法会如何表现)被称为研究技术的计算复杂性。如果你熟悉微积分中处理函数在无限接近时的行为方式,那基本上就是这样。
那么,标准正则表达式有什么好处呢?嗯,任何给定的正则表达式都可以在不超过O(N)的时间内匹配长度为N的字符串(这意味着将输入长度加倍会使所需时间加倍:它并不表示给定输入的速度)(当然,有些更快:正则表达式*可以在O(1)的时间内匹配,即常数时间)。原因很简单:记住,因为系统从每个状态只有几条路径,你永远不会“回退”,而且你只需要检查每个字符一次。这意味着即使我给你传递一个100GB的文件,你仍然能够相当快地处理它:这真是太棒了!
现在,很明显为什么你不能使用这样的机器来解析任意的XML:你可以有无限的标签嵌套,在正确解析时需要无限数量的状态。但是,如果允许递归替换,一个PCRE是Turing complete:所以它完全可以解析HTML!即使不允许,一个PCRE也可以解析任何上下文无关的语法,包括XML。所以答案是“是的,你可以”。现在,可能需要指数时间(你不能使用我们漂亮的有限状态机,所以你需要使用一个能够回溯的大型高级解析器,这意味着一个精心设计的表达式将在大文件上花费几个世纪的时间),但是仍然是可能的。
但我们快速谈一下为什么这是一个糟糕的主意。首先,尽管你会看到很多人说"哦天啊,正则表达式太强大了",但事实并非如此。它们只是简单而已。这种语言非常简单:你只需要知道一些元字符及其含义,就能(最终)理解其中的任何内容。然而,问题在于你只有这些元字符可用。你看,它们可以做很多事情,但它们旨在简洁地表达相对简单的事物,而不是试图描述一个复杂的过程。
XML确实很复杂。在其他答案中很容易找到一些例子:你不能匹配注释字段内的内容等等。用编程语言表示所有这些需要付出努力,即使有变量和函数的好处!尽管PCRE具有各种功能,但无法与之相提并论。任何手工实现都会有bug:扫描大量元字符以检查匹配的括号是困难的,而且你不能像注释代码一样注释你的代码。定义一种元语言,并将其编译成正则表达式会更容易:在那时,你可能会选择使用编写元编译器的语言来编写一个XML解析器。这对你来说更容易,运行速度更快,总体上更好。
要了解更多关于这方面的有趣信息,请查看
此网站。它以通俗易懂的方式很好地解释了所有这些内容。