如何理解javascript正则“反向引用”

代码如下:

'aaabbbcccdddeeefff'.match(/[abc]\1/g);//null
'aaabbbcccdddeeefff'.match(/([abc])\1/g);//["aa", "bb", "cc"]
'aaabbbcccdddeeefff'.match(/(([abc])\1)\1/g);//["aa", "bb", "cc"]
'aaabbbcccdddeeefff'.match(/(([abc])\1)\2/g);//["aa", "bb", "cc"]
'aaabbbcccdddeeefff'.match(/((([abc])\1)\2)\3/g);//["aaa", "bbb", "ccc"]

第一行可以验证出,反向引用针对的是分组。
第二三行结果,符合预期。
后面的就不懂了。。。
求解释,为什么??这个分组,针对的是嵌套分组,还是平行分组(/()()()/)?

按我的理解,第四行结果应当是:["aaaa", "bbbb", "cccc"],但给的测试串没有四个的,所以应当匹配无果,null。

ps:运行结果都是在chrome版本 35.0.1916.153 m下运行。

总结下结论

每个反向引用都由一个编号或名称来标识,并通过“\编号”表示法进行引用,外面的组的编号靠前。也就是说引用分组是编号排列是从外到内编排。

基于此理论,就可以很好地解释代码的运行结果。

感谢@JerryZou。

阅读 6.9k
1 个回答

首先先看下面这个例子:

"abcd".match(/(a(bc)d)/);
//result: ["abcd", "abcd", "bc"]

这个例子说明看括号匹配顺序是按左括号计算的。

再看这个例子

'aaa'.match(/(a\1)/);
//result: ['a']
'aaaaaaa'.match(/(a\1\1\1\1\1)/);
//result: ['a']

/(a\1)/在第一个括号中使用\1引用是没有意义的,看来在chrome中的测试结果表明,无论在第n个括号中有几个\n都会被忽略。

基于这个原因,我来解释一下,浏览器其实把题主的正则翻译成以下这样:

'aaabbbcccdddeeefff'.match(/[abc]\1/g);//null
'aaabbbcccdddeeefff'.match(/([abc])\1/g);//["aa", "bb", "cc"]
'aaabbbcccdddeeefff'.match(/(([abc]))\1/g);//["aa", "bb", "cc"]
'aaabbbcccdddeeefff'.match(/(([abc]))\2/g);//["aa", "bb", "cc"]
'aaabbbcccdddeeefff'.match(/((([abc]))\2)\3/g);//["aaa", "bbb", "ccc"]

下面三行中的第一个\1其实被忽略了,所以此处结果合情合理。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏