【问题标题】:Does order not matter in regular expressions?正则表达式中的顺序不重要吗?
【发布时间】:2020-02-23 17:09:39
【问题描述】:
我正在查看这个 stackoverflow 链接 (Regular expression for odd number of a's) 中提出的问题,它被要求找到具有奇数个 a 而不是 Σ = {a,b} 的字符串的正则表达式。
有效的顶级评论给出的答案是b*(ab*ab*)*ab*。
我很困惑 - a 被放置在最后一个 b* 之前,这个顺序真的重要吗?为什么不能改为b*a(ab*ab*)*b*(a 放在第一个b* 之后),或者它的任何其他排列?
我感到困惑的另一件事是为什么它是(ab*ab*)* 而不是(b*ab*ab*)*。 b*ab*ab* 不是“正好有 2 个 a”更准确的定义吗?
【问题讨论】:
标签:
regex
computer-science
regular-language
automata
【解决方案1】:
为什么不能改为b*a(ab*ab*)*b*?
b*a(ab*ab*)*b* 不起作用,因为它要求字符串在第一个非前导 b 之前有两个连续的 as,不是吗?例如,abaa 不会与您建议的正则表达式匹配。在Regex101 之类的网站上使用正则表达式调试器亲自查看。
另一方面,将整个 ab* 部分移到开头 (b*ab*(ab*ab*)*) 也可以。
为什么是(ab*ab*)* 而不是(b*ab*ab*)*?
(b*ab*ab*)* 确实有效,但第一个 b* 是非常多余的,因为无论剩下的 b 将与组中的最后一个 b* 匹配。在组之前还有一个b*,这导致b*无法匹配任何内容,因此它是多余的。
【解决方案2】:
有无数个等价的正则表达式可以生成给定的(无限的)正则语言。在某些情况下,某些作者可能更喜欢特定的表达式:一个人可能更喜欢最小的表达式,或者显示结构或对称性的表达式,甚至是简化归纳证明中的推理的表达式。
您对移动 a 的特别建议是不够的,因为如上所述,这确保子字符串 aa 将出现在具有多个 a 的任何字符串中。但是,可以将 abab 更改为 baba 以使该放置起作用。选择 babab* 将适用于任一展示位置。你甚至可以选择像 bab + bababab + (babab*) 这样的表达式a(babab*) 根据您的应用程序可能会很好地使用。像 b*(abab)ab* 这样的东西具有最小的优点(如果它不是严格最小的,它必须非常接近)。