为啥在使用带有量词的字符类时在反向引用中捕获最右边的字符?

Posted

技术标签:

【中文标题】为啥在使用带有量词的字符类时在反向引用中捕获最右边的字符?【英文标题】:Why is the rightmost character captured in backreference when using a character class with quantifiers?为什么在使用带有量词的字符类时在反向引用中捕获最右边的字符? 【发布时间】:2011-09-23 17:13:16 【问题描述】:

如果我有模式 ([a-z])2,4 和字符串“ab”,我希望在反向引用 \1 中看到什么?

我得到的是“b”,但为什么是“b”而不是“a”?

我确信有一个有效的解释,但是在各种解释正则表达式的网站上阅读,我还没有找到一个。有人吗?

【问题讨论】:

您通常也希望在重复因子周围加上括号 (([a-z]2,4))。否则,你会得到你所得到的(这就是你应得的)。为什么它应该是'a'而不是'b'?格式不正确;不完全错误,但写得不太好。 谢谢乔纳森。所以你是说这个操作的结果是不确定的,实现可以随意给我任何喜欢的东西? 你可以在这里找到解释:regular-expressions.info/brackets.html#repeat。当你在它的时候,阅读页面的其余部分,然后阅读网站的其余部分:) 排序:查看来自 Kobi 的不错的链接。我是说我真的不记得它是否是定义的和确定的,但链接说“是的,它是定义的和确定的——最后一个字符是被捕获的”。这个解释很有道理。 Kobi - 这个解释很完美,正是我想要的。非常感谢。 【参考方案1】:

我不确定为什么没有人将此作为答案,但对于任何访问此页面并提出类似问题的人来说,答案基本上就是这个正则表达式:

([a-z])2-4

将匹配az 之间的单个 字符,至少24 次。它将分别匹配每个字符,覆盖之前匹配并存储到反向引用中的任何内容(即表达式中() 字符之间的任何内容)。

类似的表达方式(在问题的cmets中建议):

([a-z]2,4)

移动反向引用以包围整个匹配项(2-4 字符 a-z)而不是单个字符。

括号表示捕获反向引用。当重复在捕获内部时(第二个示例),它将捕获构成该重复的所有字符。当重复在捕获之外时(第一个示例),它将捕获一个字母,然后重复该过程,将下一个字母捕获到相同的反向引用中,从而覆盖它。在这种情况下,它将重复该过程最多 2 次,每次都覆盖它。

因此,与目标 abc 匹配将导致 \1 等于 c。将目标与abcd 匹配将导致\1 等于d。如果有更多字母,并且取决于用于运行正则表达式的函数(和语言),目标abcde 可能无法匹配,或者可能导致反向引用\1 等于d(因为@987654341 @ 不是匹配的一部分)。

如果您使用whole match 反向引用(通常是$&$0,但也有\&\0 和在 Tcl 中,只是一个 & 字符) - 这将返回与整个正则表达式匹配的整个字符串。

【讨论】:

以上是关于为啥在使用带有量词的字符类时在反向引用中捕获最右边的字符?的主要内容,如果未能解决你的问题,请参考以下文章

替换字符串中的反向引用语法(为啥是美元符号?)

PERL正则表达式笔记——概述

正则——反向引用

在 re.sub 替换模式中处理对捕获组的反向引用

具有不同量词的正则表达式捕获组

正则表达式 - 分组分组引用反向引用多选非捕获分组