为什么有这么多不同的正则表达式方言?

19

我想知道为什么会有这么多正则表达式方言。为什么看起来很多编程语言不是采用一种经过验证的方言,而是坚持自己写。

就像这些。

我的意思是,我明白其中一些确实有非常不同的后端。但这不应该被程序员抽象出来吗?

我更关注的是奇怪但微小的差异,例如在一种语言中括号必须被转义,而在另一种语言中则是字面值。或者特殊字符的含义有所不同。

是否有任何特殊原因我们不能拥有某种通用的正则表达式方言?我认为这会让那些需要在多种编程语言中工作的程序员更容易。


我不知道,也许每种方言的开发者都认为自己的比其他所有方言都好,或者可能在当时它适合特定的需求,而其他方言还没有支持,然后当其他人决定实现这些功能时,他们认为自己可以做得更好。毕竟,并没有中央正则表达式管理委员会。 - FrustratedWithFormsDesigner
2
这不是 POSIX 应该做的事情吗?:-) - BigBeagle
1
如果您想了解一些历史背景,可以查看https://dev59.com/tGct5IYBdhLWcg3wvf7K#11857890。 - tripleee
4个回答

15

因为正则表达式只有三种操作:

  • 连接
  • 并集|
  • 克林闭包*

其它所有的都是扩展或语法糖,没有标准化的来源。像捕获组、向后引用、字符类、基数操作等都是对正则表达式原始定义的补充。

其中一些扩展使得“正则表达式”不再是正则的。由于这些额外的功能,它们能够决定非正则语言,但我们仍然称它们为正则表达式。

随着人们添加更多扩展,他们通常会尝试使用其他常见的正则表达式变体。这就是为什么几乎每个方言都使用X+来表示“一个或多个X”,这本身只是写XX*的快捷方式。

但是当添加新功能时,没有标准化的依据,所以某人必须想出一些东西。如果有多个设计者团队在大约同一时间想出了类似的想法,则它们将具有不同的方言。


“没有标准化的基础”这种说法并不正确;POSIX规范了许多这些功能,但不幸的是,它们规定了两个不同的变体,并且许多实现偏离或扩展了POSIX所规定的内容。当前的事实上的标准似乎大致是Perl/PCRE,它扩展了POSIX ERE,尽管再次强调,没有正式的标准,并且可用的实现在某些细节上有所不同。 - tripleee
@tripleee:并没有写明不能指定方言(或者从未这样做过),但是答案解释了为什么所有这些不同的方言被不同地指定(至少都是正式的,所以它们被指定了,如果只有实现才指定)。在我看来,这是一个被要求的问题,我觉得答案非常有见地,很有道理。是的,POSIX对BRE和ERE有规范。但是 POSIX 的 sed 只支持其中一种(根据规范),而 POSIX 的 grep 支持两种(但可能仅仅是根据规范)。还是反过来? - hakre
@hakre 我不确定我理解你的评论。创新有时需要偏离现有规范,以提出新的东西;而整合阶段则需要尝试明确共同点,例如在下一次演进之前制定一个新的标准。我认为对于基于PCRE的方言来说,我们还没有达到那个阶段。sed 在进化过程中陷入了一种奇怪的境地,因为 POSIX 只为其指定了 BRE 语义(虽然事实上大多数 sed 实现也支持使用 -E-r 来支持 ERE,并且一些实现还支持 Perl 的简写形式,如 \s\d)。 - tripleee
1
好的,让我试试,因为我也必须承认,我在表达这个问题上遇到了困难,因为它非常抽象。如前所述,只有这三个构造就足以完全描述正则表达式,不需要其他东西。然而,尽管如此强大,我们很容易添加更多功能来丰富它。可以称之为奢侈或舒适。我们希望工具的改进也能实现这一点。但请注意,这会导致各种方言的出现,因为很多人都在这样做。但没有人在科学上被要求遵循某种方式。因此,方言缺乏标准化。无需责怪,顺便说一句。 - hakre

3
出于同样的原因我们有许多不同的语言。一些人将尝试改进他们的工具,同时其他人则会抵制变化。C/C++/Java/C# 无所不在。

2
当有人说“C”时,我知道他们不是在说“Java”。当有人说“这个编辑器理解正则表达式”时,就像在说“这台计算机理解编程语言”。了解是哪种编程语言会很有帮助。正则表达式已经成为一个泛指,好或坏都有可能。 - Ubuntourist
1
@Ubuntourist 我同意你的观点,难点在于为特定变体和规则集制定通用接受的标签,这本身就很麻烦,因此我的回答是它会演变成“巴别塔”局面。 - Kelly S. French

2
“我让它更好”的编程症候群会导致这些问题。标准也是如此。人们试图制定下一个“最佳”标准来替换所有其他标准,结果变成了我们都必须学习/设计的另一种东西。

必须提到的xkcd参考:https://xkcd.com/927/ - Jasha

2

我认为其中一个重要问题是谁将负责设置和维护标准语法,并确保在不同环境下的兼容性。

此外,如果正则表达式必须在其自己独特的字符串操作规则解析器/编译器内进行解析,则这可能会导致在转义和字面上做出不同的事情。

一个好的策略是花时间了解正则表达式算法本身在更抽象的层次上如何工作;然后实现任何特定的语法会变得更加容易。类似于每种编程语言都有其自己的构造条件语句和循环的语法,但仍然完成相同的抽象任务。


1
也许还可以参考https://dev59.com/k2Ij5IYBdhLWcg3wcEuI - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接