Regex 有人能解释这些正则表达式的结果吗

Regex 有人能解释这些正则表达式的结果吗,regex,Regex,我测试了一些随机的正则表达式,发现了一些奇怪的结果。假设我们有正则表达式(ab |(ba)*| a)*它与aba不匹配,但是如果我去掉内星,(ab |(ba)| a)*或者如果我切换术语的顺序,(a | ab |(ba)**这两种情况现在匹配aba。那么为什么会这样呢?这与歧义或嵌套*有关吗?我知道这是一个奇怪的测试用例,内部*是多余的,但我只想了解这些结果。我正在使用regex101.com进行测试。您的假设是错误的:它与aba匹配,请参阅 关键是“正则表达式”更喜欢匹配的内容有所不同。但是,

我测试了一些随机的正则表达式,发现了一些奇怪的结果。假设我们有正则表达式
(ab |(ba)*| a)*
它与
aba
不匹配,但是如果我去掉内星,
(ab |(ba)| a)*
或者如果我切换术语的顺序,
(a | ab |(ba)**
这两种情况现在匹配
aba
。那么为什么会这样呢?这与歧义或嵌套*有关吗?我知道这是一个奇怪的测试用例,内部*是多余的,但我只想了解这些结果。我正在使用regex101.com进行测试。

您的假设是错误的:它与
aba
匹配,请参阅

关键是“正则表达式”更喜欢匹配的内容有所不同。但是,如果强制正则表达式从头到尾匹配,它将完全匹配
aba

更多细节:如果使用析取模式(例如,
r
r
s
其他正则表达式):正则表达式“喜欢”在右正则表达式
s
上选择左正则表达式
r
。例如,如果正则表达式表示
(a | aa)*
,而输入为
aa
,则可以两次匹配第一项,或者使用第二项。在这种情况下,正则表达式喜欢选择第一项两次

重复也是如此,正则表达式希望尽可能多地重复Kleene star
r*
中的项。

交替运算符(
)短路,并始终尝试匹配最左边的子模式,直到该子模式失败,此时它将尝试匹配下一个。只能匹配非重叠模式。空字符串匹配会导致当前贪婪模式结束,因为空字符串可以无限匹配,无论贪婪与否,继续这样做都没有意义。贪婪并不一定意味着愚蠢

因此,对于模式
(ab |(ba)*|a)*
,以及字符串
“aba”
,它将从字符串的开头匹配“ab”。由于在最外层的捕获组*上使用贪婪量词,正则表达式将继续尝试与最外层的捕获组进行更长的匹配。匹配迭代器将位于第3个字符处,它将尝试匹配“ab”,但将失败。然后,当意识到它可以无限次地使用空字符串匹配
(ba)*
时,它将结束匹配(不使用
(ba)*
捕获任何内容,也不尝试匹配最后一个可选模式
a
)并返回最外层重复捕获组的最后一次迭代

现在,如果您切换与交替运算符链接的子模式的顺序,如
(ab | a |(ba)*)**
,将匹配整个字符串,因为匹配器能够使用
a
推进匹配迭代器,然后使用第三个可选子模式的最终空字符串匹配完成匹配

(ab |(ba)| a)*
也起作用,因为第二个备选方案无法与空字符串匹配,因此一旦它无法匹配
ba
,它就会成功地继续尝试匹配
a

另一种类似的修复方法是使用
(ab |(ba)+a)*
。这将正确地导致第二个备选方案正确失败,而不是匹配它

最后一种修复方法是在字符串的末尾使用锚点,通常用
$
表示。模式
(ab |(ba)*|a)*$
能够在匹配第二个备选方案时正确失败,因为它意识到这样做永远不会到达字符串的末尾。它最终仍将匹配第二个备选方案,但仅在匹配迭代器遍历到字符串末尾之后


这就是为什么从最外层的捕获组只能看到一个带有字符串“aba”的捕获。模式
(ba)*
将始终与索引2-2(或任何空子字符串)匹配,然后结束当前匹配并阻止下一个
a
匹配,但不会捕获任何内容,除非字符串中有一个显式的
'ba'
,且该字符串不与任何先前的可选项重叠。

(a | ab |(ba)*)*
和您发布的
(ab | a |(ba)*)*
与aba匹配,但原始的
(ab |(ba)*(a)*
不匹配,但我不明白为什么会这样。@Shashank为什么删除您的答案?是错误的吗?我的答案中有一些不正确的术语。基本上我是这么说的(ba)*在我的答案中的某些点不匹配,它确实匹配,但它与导致贪婪匹配者停止寻找的空字符串匹配(它是贪婪的,但并不愚蠢)。答案现在是固定的。:)好的,你的答案现在完全有意义了,我接受了它,谢谢:)所以要强制正则表达式从头到尾匹配,您需要添加
^expr$
其中
expr
是您的原始正则表达式?这是否意味着强制正则表达式从头到尾匹配始终是最好的做法?
^
$
是强制正则表达式在字符串的开头和结尾匹配。