请大神帮忙理解下正则表达式
>>> 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')] # 看不懂结果
最开始前两个为何无 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 返回的就是正则整组此时匹配到的结果
列表中一个 元组表示 匹配到的元素,元组中的正则元素对应每组匹配的元素
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 返回的就是正则整组此时匹配到的结果
列表中一个 元组表示 匹配到的元素,元组中的正则元素对应每组匹配的元素 lzb1001 发表于 2022-4-29 10:47
谢谢大神解疑释惑,以下第3个还是看不懂,不理解
1、ok
---为何无I?
理由同问题1,(\w+)(\w+) 匹配最少需要两个字母相邻
---为何表达式中无空格也能匹配得上?
而空格在正则表达式中就是和普通符号一样,表示匹配字符中的 空格,正则匹配是去找里面符合表达式的字符,要理解正则匹配的原理
好好理解理解问题1的解释,\w 匹配字母,配合 + 号表示匹配 1~多个 字母,而匹配过程默认是贪婪匹配,会尽可能的匹配多个,
使用当 第一个 \w+ 开始匹配时,会尽量匹配到极限,而剩下最后一个字母给 第二个 \w+ 匹配,这样才保证可以匹配到,
这也是为什么 分组会呈现这种情况,你可以将第一个匹配带上 ? 号,表示非贪婪匹配,结果会正好和这字符串长度相反
'(\w+?)(\w+)'
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')]
所以每行代码在回车运行之前,说实话真不知道返回的结果,不知道是不是因为还没有真正理解? 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'), ('!')] lzb1001 发表于 2022-4-29 11:49
如果我想匹配出如下完整的result结果,代码中……应如何写表达式呢?
>>> result = re.findall(r'…… ...
'\w+|!'
本帖最后由 lzb1001 于 2022-4-29 14:43 编辑
Twilight6 发表于 2022-4-29 12:11
'\w+|!'表示后面的字符串匹配w+或!,所以匹配的结果是:
w+匹配I love FishC com或I love FishC_com
!匹配!
是这个意思吗?
p.s:使用'\w+|!'将遗漏.com中的点. 本帖最后由 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+ 或 ! ,匹配成功就返回,同上类似步骤 Twilight6 发表于 2022-4-29 12:11
如果要把'I love FishC.com!'里面的单词以及空格、点号.、感叹号!一个不拉的全部都匹配出来:
>>> result = re.findall(r'\w+|\s|\.|!', 'I love FishC.com!')
>>> result
['I', ' ', 'love', ' ', 'FishC', '.', 'com', '!']
有没有更简单的正则表达式可以实现上面的效果呢?
lzb1001 发表于 2022-4-29 14:54
如果要把'I love FishC.com!'里面的单词以及空格、点号.、感叹号!一个不拉的全部都匹配出来:
>>> r ...
差不多就这样,我研究不深也不知如何简洁了
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', '!']
页:
[1]