鱼C论坛

 找回密码
 立即注册
查看: 1697|回复: 8

[已解决]关于正则表达式的疑惑

[复制链接]
发表于 2020-7-8 03:19:53 | 显示全部楼层 |阅读模式

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

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

x
python 正则表达式
>>> m = re.match("([abc])+", "abc")
>>> m.groups()
('c',)
#这里为什么不是(‘a’,'b’,‘c’)?

###groups会返回所有组的,那应该是返回group(0)='abc',group(1)='a'?现在返回的'c'是group几的结果?

#####查找资料有答复贪婪模式的,但还是不明白是怎么贪婪的?

下面这个例子:

复制代码
1 >>> a="123abc456"
2 >>> import re
3 >>> print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0))
4 123abc456
5 >>> print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1))
6 123

#####跟上面例子有什么区别?为什么这里不是返回'456'?


7 >>> print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2))
8 abc
9 >>> print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(3))
10 456
11 >>> print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group())
12 123abc456
13 >>> print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).groups())
14 ('123', 'abc', '456')
15 >>> print(re.search("([0-9])*([a-z])*([0-9]*)", a).groups())
16 ('3', 'c', '456')
17 >>> print(re.search("([0-9])*([a-z])*([0-9]*)", a).groups(1))
18 ('3', 'c', '456')
19 >>> print(re.search("([0-9])*([a-z])*([0-9]*)", a).group(0))
20 123abc456
21 >>> print(re.search("([0-9])*([a-z])*([0-9]*)", a).group())
22 123abc456


>>> m = re.match("(?:[abc])+", "abc")
>>> m.groups()
()
这个?:是什么意思,怎么什么输出都没有的
求详解

最佳答案
2020-7-8 04:59:13
"([abc])+"   re默认是贪婪模式。这个正则可以理解为,a or b or c 出现一次或者多次都是成功。   
"([abc])?"   使用表示非贪婪,这个正则可以理解为,a or b or c 出现零次或者一次都是成功。

去匹配“abc”是    贪婪尽可能的在成功的情况下,多匹配。所以它匹配是 a b c 都是成功的,但是总体它是一次匹配,一次尽可能多得的匹配,所以到c没有了
                         非贪婪尽可能在成功的情况下,少匹配,这里它匹配是 a b c 都是成功的,这个是成功了三次,a,b,c都会作为结果集。

m = re.match("([abc])+", "abc")

group() = group(0) = 正则表达式整体结果,因为是贪婪模式,所有abc被匹配成功。
group(1) = 分组的第一组,你匹配式只有一个组,就是一个括号,所以返回 ‘c’  并不会返回 ‘a’,在注意下结果

=============================================

跟上面例子有什么区别?为什么这里不是返回'456'?
没有区别

group() = group(0) = 正则表达式整体结果, "123abc456"均匹配成功
group(1) = 分组的第一组,这里有三组,第一组就是 123

"(?:[abc])+"    ?:  是组合使用,类似(...),表示它不是一个元祖,匹配是成功的,用group()可以看到,返回的结果是,abc。不过groups返回的都是元祖,所有没有输出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-8 04:59:13 | 显示全部楼层    本楼为最佳答案   
"([abc])+"   re默认是贪婪模式。这个正则可以理解为,a or b or c 出现一次或者多次都是成功。   
"([abc])?"   使用表示非贪婪,这个正则可以理解为,a or b or c 出现零次或者一次都是成功。

去匹配“abc”是    贪婪尽可能的在成功的情况下,多匹配。所以它匹配是 a b c 都是成功的,但是总体它是一次匹配,一次尽可能多得的匹配,所以到c没有了
                         非贪婪尽可能在成功的情况下,少匹配,这里它匹配是 a b c 都是成功的,这个是成功了三次,a,b,c都会作为结果集。

m = re.match("([abc])+", "abc")

group() = group(0) = 正则表达式整体结果,因为是贪婪模式,所有abc被匹配成功。
group(1) = 分组的第一组,你匹配式只有一个组,就是一个括号,所以返回 ‘c’  并不会返回 ‘a’,在注意下结果

=============================================

跟上面例子有什么区别?为什么这里不是返回'456'?
没有区别

group() = group(0) = 正则表达式整体结果, "123abc456"均匹配成功
group(1) = 分组的第一组,这里有三组,第一组就是 123

"(?:[abc])+"    ?:  是组合使用,类似(...),表示它不是一个元祖,匹配是成功的,用group()可以看到,返回的结果是,abc。不过groups返回的都是元祖,所有没有输出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-8 07:44:50 | 显示全部楼层
贪婪模式指的是,有几个我就要几个(匹配多次),一个的话,我也要(匹配一次)。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-8 07:59:45 | 显示全部楼层
本帖最后由 兰竹皋 于 2020-7-8 08:05 编辑
Stubborn 发表于 2020-7-8 04:59
"([abc])+"   re默认是贪婪模式。这个正则可以理解为,a or b or c 出现一次或者多次都是成功。   
"([ab ...


额,
随便说一下
1、非贪婪符号是:    +?  、 *?  、 ??  (不是单独问号)
     而关于贪婪的解释最好感觉直接从算法来说明:
     比如      re.match('a.+c', 'abbbbcdddc')     贪婪模式    : 会先从开头找匹配a,再从末尾找匹配c,中间全要
                 re.match('a.+?c', 'abbbbcdddc')    非贪婪模式 : 会先从开头找匹配a,接着a继续向后找匹配c  ...

2、楼主的疑惑应该主要是: 为什么括号()没有随+号一同增加匹配为3个吧......
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-7-8 13:59:03 | 显示全部楼层
兰竹皋 发表于 2020-7-8 07:59
额,
随便说一下
1、非贪婪符号是:    +?  、 *?  、 ??  (不是单独问号)

我的疑问比较多,主要是:
>>> m = re.match("([abc])+", "abc")
>>> m.groups()
('c',)
这个地方为什么返回的c?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-8 14:23:26 | 显示全部楼层
Stubborn 发表于 2020-7-8 04:59
"([abc])+"   re默认是贪婪模式。这个正则可以理解为,a or b or c 出现一次或者多次都是成功。   
"([ab ...

有一个地方还是不太明白,再请教下:
>>> m = re.match("([abc])+", "abc")
>>> m.group(1)
'c'
>>> m.groups()
('c',)

这个地方group(1)应该理解为(a or b or c)去匹配'abc',我理解是第一次去匹配a就会成功,不应该返回'a'吗?
groups()应该返回所有匹配子组的结果,那应该返回group(0)和group(1)的结果,不应该是'abc'和‘a’?为什么返回了一个'c'?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-8 14:33:33 | 显示全部楼层
本帖最后由 Stubborn 于 2020-7-8 14:35 编辑
fanbula 发表于 2020-7-8 14:23
有一个地方还是不太明白,再请教下:
>>> m = re.match("([abc])+", "abc")
>>> m.group(1)


贪婪,尽可能多的匹配,a成功,会再次尝试匹配,最终匹配到c之后,匹配失败,结束匹配,这个c是最终结果。

group() = group(0) = 正则表达式整体结果,因为是贪婪模式,所有abc被匹配成功。返回abc
group(1) = 分组的第一组,你匹配式只有一个组,就是一个括号,所以返回 ‘c’  并不会返回 ‘a’

c是最终匹配结果。就是你正则式匹配出来的结果。因为是贪婪模式,不是a,也不会是b


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-8 17:34:06 | 显示全部楼层
Stubborn 发表于 2020-7-8 14:33
贪婪,尽可能多的匹配,a成功,会再次尝试匹配,最终匹配到c之后,匹配失败,结束匹配,这个c是最终结果 ...

group()=group(0)我能理解,那groups()呢?这个返回是只包含group(1)这个子组,不包含整体的group(0)的结果,是这样理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-8 17:38:18 | 显示全部楼层
本帖最后由 Stubborn 于 2020-7-8 17:40 编辑
fanbula 发表于 2020-7-8 17:34
group()=group(0)我能理解,那groups()呢?这个返回是只包含group(1)这个子组,不包含整体的group(0) ...


groups()  返回匹配的结果集,最终结果,和正则表达式整体结果不一样
group(1)  1以后,就等于在结果集里面取某一个结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-20 01:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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