我正在尝试使用正则表达式来查找字符串中最长的重复子字符串。例如:**当输入为“aabbcc”时,预期输出应为“ccc”(重复3次)**我最终使用str.match(/(\w)\1+/g)
得到了答案。因此,当const str = 'aabbccc'
并运行str.match(/(\w)\1+/g)
时,输出将为['aa', 'bb', 'ccc']
但我使用的是str.match(/(\w\1+)/g)
,输出为['a', 'a', 'b', 'b', 'c', 'c', 'c']
有人能解释一下为什么吗?
我想:\w
:任何单词,\1+
:重复一次或多次\w\1+
:任何单词重复一次或多次(\w\1+)
:将任何重复的单词作为一个组捕获
3条答案
按热度按时间watbbzwu1#
www.example.com no-useless-backreference上有相关说明esling.org
在JavaScript正则表达式中,定义属于模式的另一个可选部分的组的反向引用、出现在反向引用之后的组的反向引用、包含该反向引用的组的反向引用或者负查找内部的组的反向引用在语法上是有效的。在这些情况中的任何一种中,反向引用总是以仅匹配零长度(空串)而结束,而不管反向引用和组出现在其中的上下文如何。
总是成功匹配零长度但不能匹配其他任何内容的反向引用是无用的。它们基本上被忽略,可以在不改变正则表达式行为的情况下被删除。
在https://262.ecma-international.org/处还有一个注解
注2
形式为\后跟非零十进制数n的转义序列与第n组捕获括号的结果匹配(22.2.2.1)。如果正则表达式的捕获括号少于n个,则会出错。如果正则表达式有n个或更多捕获括号,但第n个括号由于未捕获任何内容而未定义,则反向引用始终成功。
因此,模式
(\w\1+)
捕获了单个单词字符,由于忽略了反向引用,因此仅写入\w
也可以获得相同的结果polkgigr2#
(\w)
匹配第一个捕获组的单词字符,\1+
匹配该第一个捕获组的一个或多个匹配项。这将查找重复字符。在
(\w\1+)
中,\1+
位于第一个捕获组内,因此它尝试匹配包含它的组的一个或多个匹配项。gfttwv5a3#
1 .
/(\w)\1+/g
使用两组括号:(\w)
,它接受任何单词字符并创建一个组。\1+
是对第一个捕获组(\w)
的反向引用,并匹配该捕获字符的一个或多个重复项。+
限定符表示“一个或多个”。此表达式匹配字符串中的所有重复子字符串,并返回字符串数组。/(\w\1+)/g
使用2组括号,(\w)
捕获一个单词字符,第二个\1+
匹配一个或多个与上次捕获相同的字符,但这一个没有创建一个组,并在此匹配重复字符作为数组中的单个字符。