鱼C论坛

 找回密码
 立即注册
查看: 1338|回复: 11

[已解决]请大神帮忙理解下正则表达式

[复制链接]
发表于 2022-4-29 09:52:14 | 显示全部楼层 |阅读模式

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

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

x
>>> result = re.search(r'(\w+)(\w+)', 'I love FishC.com!') # search+无空格+.com
>>> result
<re.Match object; span=(2, 6), match='love'> # 为何无I?

>>> result = re.search(r'(\w+)(\w+)', 'I love FishC_com!') # search+无空格+_com
>>> result
<re.Match object; span=(2, 6), match='love'> # 为何无I?

>>> result = re.search(r'(\w+) (\w+)', 'I love FishC.com!') # search+1个空格+.com
>>> result
<re.Match object; span=(0, 6), match='I love'>

>>> result = re.search(r'(\w+) (\w+)', 'I love FishC_com!') # search+1个空格+_com
>>> result
<re.Match object; span=(0, 6), match='I love'>

>>> result = re.search(r' (\w+) (\w+)', 'I love FishC.com!') # search+2个空格+.com
>>> result
<re.Match object; span=(1, 12), match=' love FishC'> # 为何无I?

>>> result = re.search(r' (\w+) (\w+)', 'I love FishC_com!') # search+2个空格+_com
>>> result
<re.Match object; span=(1, 16), match=' love FishC_com'> # 为何无I?

>>> result = re.findall(r'(\w+)(\w+)', 'I love FishC.com!') # findall+无空格+.com
>>> result
[('lov', 'e'), ('Fish', 'C'), ('co', 'm')] # 看不懂结果

>>> result = re.findall(r'(\w+)(\w+)', 'I love FishC_com!') # findall+无空格+_com
>>> result
[('lov', 'e'), ('FishC_co', 'm')] # 看不懂结果

>>> result = re.findall(r'(\w+) (\w+)', 'I love FishC.com!') # findall+1个空格+.com
>>> result
[('I', 'love')] # 看不懂结果

>>> result = re.findall(r'(\w+) (\w+)', 'I love FishC_com!') # findall+1个空格+_com
>>> result
[('I', 'love')] # 看不懂结果

>>> result = re.findall(r' (\w+) (\w+)', 'I love FishC.com!') # findall+2个空格+.com
>>> result
[('love', 'FishC')] # 看不懂结果

>>> result = re.findall(r' (\w+) (\w+)', 'I love FishC_com!') # findall+2个空格+_com
>>> result
[('love', 'FishC_com')] # 看不懂结果
最佳答案
2022-4-29 10:19:55

最开始前两个为何无 I 的原因是 :

+ 是匹配前面的 1 至 多次,而你 I 只有一个字符,前后都没有在相邻的字母了

即只能匹配上 (\w+)(\w+) 前面一组正则,而后面一组匹配不上,自然就匹配失败。(\w+)(\w+) 的匹配最少需要两个字母

>>> result = re.search(r' (\w+) (\w+)', 'I love FishC.com!') # search+2个空格+.com
>>> result
<re.Match object; span=(1, 12), match=' love FishC'> # 为何无I?


' (\w+) (\w+)' 匹配不上 I 呀,I 前面没有空格,而你正则开始第一个就是空格


>>> result = re.findall(r'(\w+)(\w+)', 'I love FishC.com!') # findall+无空格+.com
>>> result
[('lov', 'e'), ('Fish', 'C'), ('co', 'm')] # 看不懂结果


因为你正则表达式中分组了,findall 返回的就是正则整组此时匹配到的结果

列表中一个 元组表示 匹配到的元素,元组中的正则元素对应每组匹配的元素

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

使用道具 举报

发表于 2022-4-29 10:19:55 | 显示全部楼层    本楼为最佳答案   

最开始前两个为何无 I 的原因是 :

+ 是匹配前面的 1 至 多次,而你 I 只有一个字符,前后都没有在相邻的字母了

即只能匹配上 (\w+)(\w+) 前面一组正则,而后面一组匹配不上,自然就匹配失败。(\w+)(\w+) 的匹配最少需要两个字母

>>> result = re.search(r' (\w+) (\w+)', 'I love FishC.com!') # search+2个空格+.com
>>> result
<re.Match object; span=(1, 12), match=' love FishC'> # 为何无I?


' (\w+) (\w+)' 匹配不上 I 呀,I 前面没有空格,而你正则开始第一个就是空格


>>> result = re.findall(r'(\w+)(\w+)', 'I love FishC.com!') # findall+无空格+.com
>>> result
[('lov', 'e'), ('Fish', 'C'), ('co', 'm')] # 看不懂结果


因为你正则表达式中分组了,findall 返回的就是正则整组此时匹配到的结果

列表中一个 元组表示 匹配到的元素,元组中的正则元素对应每组匹配的元素

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

使用道具 举报

 楼主| 发表于 2022-4-29 10:47:57 | 显示全部楼层
Twilight6 发表于 2022-4-29 10:19
最开始前两个为何无 I 的原因是 :

+ 是匹配前面的 1 至 多次,而你 I 只有一个字符,前后都没有在相 ...

谢谢大神解疑释惑,以下第3个还是看不懂,不理解

1、ok

最开始前两个为何无 I 的原因是 :

+ 是匹配前面的 1 至 多次,而你 I 只有一个字符,前后都没有在相邻的字母了

即只能匹配上 (\w+)(\w+) 前面一组正则,而后面一组匹配不上,自然就匹配失败。(\w+)(\w+) 的匹配最少需要两个字母

2、ok

>>> result = re.search(r' (\w+) (\w+)', 'I love FishC.com!') # search+2个空格+.com
>>> result
<re.Match object; span=(1, 12), match=' love FishC'> # 为何无I?


' (\w+) (\w+)' 匹配不上 I 呀,I 前面没有空格,而你正则开始第一个就是空格

3、还是不理解:

---为何无I?
---为何表达式中无空格也能匹配得上?
---为何love拆分成lov+e,而不是其他比如lo+ve,FishC和com的拆分也不理解

>>> result = re.findall(r'(\w+)(\w+)', 'I love FishC.com!') # findall+无空格+.com
>>> result
[('lov', 'e'), ('Fish', 'C'), ('co', 'm')] # 看不懂结果


因为你正则表达式中分组了,findall 返回的就是正则整组此时匹配到的结果

列表中一个 元组表示 匹配到的元素,元组中的正则元素对应每组匹配的元素
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-29 11:01:12 | 显示全部楼层
lzb1001 发表于 2022-4-29 10:47
谢谢大神解疑释惑,以下第3个还是看不懂,不理解

1、ok



---为何无I?


理由同问题1,(\w+)(\w+) 匹配最少需要两个字母相邻

---为何表达式中无空格也能匹配得上?


而空格在正则表达式中就是和普通符号一样,表示匹配字符中的 空格,正则匹配是去找里面符合表达式的字符,要理解正则匹配的原理

好好理解理解问题1的解释,\w 匹配字母,配合 + 号表示匹配 1~多个 字母,而匹配过程默认是贪婪匹配,会尽可能的匹配多个,

使用当 第一个 \w+ 开始匹配时,会尽量匹配到极限,而剩下最后一个字母给 第二个 \w+ 匹配,这样才保证可以匹配到,

这也是为什么 分组会呈现这种情况,你可以将第一个匹配带上 ? 号,表示非贪婪匹配,结果会正好和这字符串长度相反
'(\w+?)(\w+)'

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

使用道具 举报

 楼主| 发表于 2022-4-29 11:39:46 | 显示全部楼层
Twilight6 发表于 2022-4-29 11:01
理由同问题1,(\w+)(\w+) 匹配最少需要两个字母相邻

我测试了下面几个:

>>> result = re.search(r'(\w+?)(\w+)!', 'I love FishC_com!')
>>> result
<re.Match object; span=(7, 17), match='FishC_com!'>
>>> result = re.findall(r'(\w+?)(\w+)!', 'I love FishC_com!')
>>> result
[('F', 'ishC_com')]
>>> result = re.findall(r'(\w+)(\w+)!', 'I love FishC_com!')
>>> result
[('FishC_co', 'm')]

所以每行代码在回车运行之前,说实话真不知道返回的结果,不知道是不是因为还没有真正理解?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-29 11:49:49 | 显示全部楼层
Twilight6 发表于 2022-4-29 11:01
理由同问题1,(\w+)(\w+) 匹配最少需要两个字母相邻

如果我想匹配出如下完整的result结果,代码中……应如何写表达式呢?

>>> result = re.findall(r'……', 'I love FishC.com!')
>>> result
[('I'), ('love'), ('FishC'), ('com'), ('!')]

>>> result = re.findall(r'……', 'I love FishC_com!')
>>> result
[('I'), ('love'), ('FishC_com'), ('!')]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-29 12:11:56 | 显示全部楼层
lzb1001 发表于 2022-4-29 11:49
如果我想匹配出如下完整的result结果,代码中……应如何写表达式呢?

>>> result = re.findall(r'…… ...


'\w+|!' 

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

使用道具 举报

 楼主| 发表于 2022-4-29 14:41:06 | 显示全部楼层
本帖最后由 lzb1001 于 2022-4-29 14:43 编辑


'\w+|!'表示后面的字符串匹配w+或!,所以匹配的结果是:

w+匹配I love FishC com或I love FishC_com
!匹配!

是这个意思吗?

p.s:使用'\w+|!'将遗漏.com中的点.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-29 14:50:26 | 显示全部楼层
本帖最后由 Twilight6 于 2022-4-29 14:52 编辑
lzb1001 发表于 2022-4-29 14:41
'\w+|!'表示后面的字符串匹配w+或!,所以匹配的结果是:

w+匹配I love FishC com或I love FishC_com ...



findall 是查找多次,直到全部检索结束查找完毕,所以 \w+ 匹配 I love FishC.com! 字符串的过程是:

第一次贪婪匹配到 I ,结束,返回到列表中,然后从 I 后面空格开始继续匹配

第二次贪婪匹配成功是匹配到 love,匹配结束,返回到列表中,同理继续往下匹配

...

直到全部匹配结束,匹配出了 I、love、FishC.com ,不是一次性就直接匹配了 I love FishC.com 整个字符串,因为 \w 不与非字母以及下划线进行匹配

这样能理解吗?最后 \w+|! 就是每次匹配 \w+ 或 ! ,匹配成功就返回,同上类似步骤
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-29 14:54:56 | 显示全部楼层


如果要把'I love FishC.com!'里面的单词以及空格、点号.、感叹号!一个不拉的全部都匹配出来:

>>> result = re.findall(r'\w+|\s|\.|!', 'I love FishC.com!')
>>> result
['I', ' ', 'love', ' ', 'FishC', '.', 'com', '!']


有没有更简单的正则表达式可以实现上面的效果呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-29 14:58:29 | 显示全部楼层
lzb1001 发表于 2022-4-29 14:54
如果要把'I love FishC.com!'里面的单词以及空格、点号.、感叹号!一个不拉的全部都匹配出来:

>>> r ...



差不多就这样,我研究不深也不知如何简洁了

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

使用道具 举报

 楼主| 发表于 2022-4-29 15:12:52 | 显示全部楼层
Twilight6 发表于 2022-4-29 14:58
差不多就这样,我研究不深也不知如何简洁了

感谢大神的不吝赐教,谢谢!

>>> result = re.findall(r'\w+|\s|\.|!', 'I love FishC.com!')
>>> result
['I', ' ', 'love', ' ', 'FishC', '.', 'com', '!']

>>> result = re.findall(r'\w+|\s|!', 'I love FishC_com!')
>>> result
['I', ' ', 'love', ' ', 'FishC_com', '!']
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-18 14:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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