日期:2014-05-18  浏览次数:20394 次

(\w)\1{4,}和(\w){4,}\1和(\w)\1{4,}\1的困惑
(\w)\1{4,}和(\w){4,}\1和(\w)\1{4,}\1的困惑

" 反向引用 \1, \2...
  表达式在匹配时,表达式引擎会将小括号 "( )" 包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。这一点,在前面的举例中,已经多次展示了。在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来指定所要的范围。比如前面的 "<td>(.*?)</td>"。

  其实,"小括号包含的表达式所匹配到的字符串" 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面 "括号内的子匹配已经匹配到的字符串"。引用方法是 "\" 加上一个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号。
"-----------自己这段话理解的不是很好,所以下面的例子就更晕

(\w)\1{4,}和(\w){4,}\1和(\w)\1{4,}\1" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时的困惑
(\w)\1{4,}匹配 ccccc 999999999
(\w){4,}\1匹配 ccccc 111121111 999999999
(\w)\1{4,}\1匹配 999999999
到底\1做了什么呀? 反向引用 \1, \2...那段话真是理解的不是很好。。。
可否说下呢?谢谢了
(\w)\1{4,}匹配 ccccc 999999999
(\w){4,}\1匹配 ccccc 111121111 999999999
(\w)\1{4,}\1匹配 999999999
youngord(621852223) 22:16:20
那\1位置不同,差异那么大呀

------解决方案--------------------
这个绝不是一两句话能讲得清的,要看你的正则基础知识掌握到什么程度了

从你的提问来看,我认为你掌握的并不好,或者说还不够

首先是捕获组的概念,这里用到的就是普通的捕获组,至于其它的命名捕获组和非捕获组,以及零宽度捕获组的概念,自己找教程看下吧,普通的捕获组就是(exp)这种形式的,而其它的(?<name>exp),(?:exp),(?!exp),(?=exp),(?<=exp),(?<!exp)等等,这里用不到,你自己看下

接下来是修饰匹配次数的{m,n},表示表达式重复的次数

反向引用 \1, \2... 的概念就是你贴的了

说下你给的例子的区别
(\w)\1{4,}和(\w){4,}\1和(\w)\1{4,}\1

\w A~Z,a~z,0~9,_ 中任意一个

(\w)\1{4,} \1是对第一个捕获组的反向引用,这个正则的第一个捕获组就是(\w);这里(\w)匹配一个字符,\1匹配一个字符,它的内容需要与(\w)匹配的内容相同;{4,}表示重复次数,这个正则中它修饰的是\1,也就是\1要重复4次以上,整个加起来,应该是至少5个字符,而且都是(\w)匹配到的字符,例子中只有ccccc 999999999符合要求

(\w){4,}\1 \1意义同上,匹配到字符个数同样至少为5个,但这里不同的是{4,}修饰的是(\w),而\1只重复一次,也就是只要有一个字符与前面捕获组匹配到的内容相同就够了,整个正则的意思就是,匹配到的字符串位数至少为5,前面的只要在\w范围内即可,不需要相同,只要最后两个相同就可以了。这里需要说明的一点就是(\w)匹配的内容是什么,捕获组由左向右匹配,它捕获到的内容是,整个表达式匹配成功的前提下,最后捕获到的内容,比如说如下的字符串
abcdeffg
用这个表达式匹配是能够匹配成功的,匹配到的内容是abcdeff,这里(\w)捕获到的就是f,而\1匹配的内容是后一个f
而abcdefffg匹配到的内容应该是abcdefff,至于为什么是这样,涉及到贪婪匹配,自己看下

(\w)\1{4,}\1 这个只是第一个正则的变化形式,如果以上两个理解了,这个就很好理解了,它相当于(\w)\1{5,},匹配结果要求6位以上,全都一样的字符


再给你扩展一下,正则如下
(\w\w){4,}\1
测试字符串为
aa bbbb abcdefg ccccc 111121111 999999999 abcdeffg 1111111111 abababababab

它匹配的结果是1111111111和abababababab
这里捕获组为(\w\w),它要求为两个字符,但两个字符的内容可以不同,整个表达式要求10个字符以上,而且(\w\w)匹配到的字符串,至少重复5次以上,所以只有这两个符合要求

如果以上都理解了,再去理解一下\1和\2同时出现的情况,反向引用和贪婪匹配是正则中的两个难点,这两点都理解了,正则的基本应用就没问题了,所差的也就是熟练程度了