鱼C论坛

 找回密码
 立即注册
查看: 2320|回复: 6

[已解决]正则表达式的非捕获组的问题

[复制链接]
发表于 2017-8-29 17:27:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
m = re.findall(r'[0-9a-z]{2}(?<=aa)','aabbaabb')
输出['aa', 'aa']
这个怎么分析呢?
我的分析是:
1-4个字母aabb,不匹配,但非捕获组aa不占位置,从3个字母开始查找,3-6个字母bbaa匹配,捕获bb,从5个字母aa开始查找aabb不匹配,查找结束,应该只有一个aa
请问我的分析哪有有问题呢
最佳答案
2017-9-2 10:50:22

我竟然无言以对。。。
这里就是等同于直接写aa的意思。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-8-29 18:56:12 | 显示全部楼层
因为你匹配的是2个字母或数字啊,aa正好是两个字母,所以匹配了两个,你把匹配的次数变大一点就好了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-29 20:04:50 | 显示全部楼层
没太读懂楼主要实现的效果。为什么匹配出来是[aa, aa]
简单来说就是后面的(?<=aa)指定了[0-9a-z]{2}的匹配内容就是aa。
(?<=aa)虽然不是匹配内容,但是表示了后面任意字符前面会有个aa。
假设表达式后面还有一个b,即"[0-9a-z]{2}(?<=aa)b",这里要匹配三个字符,前面两个任意[0-9a-z]都行。
但是!后面的(?<=aa)b指明了b的前面会有aa!那前面那两个任意[0-9a-z]只能是aa。

表达能力不是很好
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-29 21:18:14 | 显示全部楼层
[0-9a-z]{2}(?<=aa)

匹配到'aa'的时候,上面那个表达式的两个部分同时成立,
其他的时候,(?<=aa)不成立。
所以,结果是['aa', 'aa']
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-2 10:18:52 | 显示全部楼层
第四时空 发表于 2017-8-29 20:04
没太读懂楼主要实现的效果。为什么匹配出来是[aa, aa]
简单来说就是后面的(?

我以为[0-9a-z]{2}(?<=aa)的意思是匹配任意2个字母或数字加aa呢?为什么(?<=aa)是指定[0-9a-z]{2}一定匹配aa呢?那为什么不直接写aa
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-2 10:50:22 | 显示全部楼层    本楼为最佳答案   

我竟然无言以对。。。
这里就是等同于直接写aa的意思。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-2 11:08:12 | 显示全部楼层
ooo,我懂了,我来总结一下:
非捕获组的结构是(?:X),其中X是正则表达式
拓展一下,有4种非捕获组:
1.(?=X)    表示肯定前向查找,即在当前位置右边匹配时才可继续匹配
当(?=X) 在其他正则表达式后面时:
  1. p = re.findall(r'[0-9a-z]{2}(?=ab)','ab00ab11ab33')
  2. print(p)
  3. ['00', '11']
复制代码

表示任意2个字母或数字后如果有ab则匹配,这里的00ab和11ab,但是由于ab是非捕获组,因此不输出ab,只输出前面匹配的内容00 和11
当(?=X) 在其他正则表达式前面时:
  1. p = re.findall(r'(?=hopeful)hope','this is a hopeful hope')
  2. >>> print(p)
  3. ['hope']
复制代码

表示查找字符串'this is a hopeful hope'中是否匹配hopeful,如果匹配,则输出hope,同理,在
  1. p = re.findall(r'(?=ab)[0-9a-z]{2}','ab00ab11ab33')
  2. >>> print(p)
  3. ['ab', 'ab', 'ab']
复制代码

中,查找'ab00ab11ab33'中是否匹配ab,若匹配,输出ab


2.(?<=X)  表示肯定后向查找,即X在此位置左边匹配时才可继续查找
  1. m = re.findall(r'(?<=ab)[0-9a-z]{2}','abcdabcdab')
  2. >>> print(m)
  3. ['cd', 'cd']
复制代码

这里匹配1-4个字符abcd,和5-8个字符abcd,但是ab是非捕获组,因此不打印出来,输出cd,cd
但是,当(?<=X)放到其他正则表达式后面:
  1. m = re.findall(r'[0-9a-z]{2}(?<=ab)','abcdabcdab')
  2. >>> print(m)
  3. ['ab', 'ab', 'ab']
复制代码

指定[0-9a-z]{2}中就是ab,即字符串中存在ab才可以匹配
  1. m = re.findall(r'ab(?<=ab)','abcdabcdab')
  2. >>> print(m)
  3. ['ab', 'ab', 'ab']
复制代码

这样也是可以的,但是
  1. m = re.findall(r'abcd(?<=ab)','abcdabcdab')
  2. >>> print(m)
  3. []
复制代码

这样就不可以,因为前面的正则表达式不可以被指定为ab,因此不可以匹配,这样看来(?<=X)一般是放到前面使用,放到后面时没有什么意义的

3.(?!X)  前向否定查找
4.(?<!X)  后向否定查找
这两个和前面的不同就是不匹配X即可
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-3-1 23:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表