鱼C论坛

 找回密码
 立即注册
查看: 2104|回复: 25

[已解决]关于re.sub的空匹配问题

[复制链接]
发表于 2018-7-26 13:36:13 | 显示全部楼层 |阅读模式

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

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

x
  1. p = re.compile('x*')
  2. >>> p.sub('-', 'abxd') #正则表达式去匹配abxd,碰到x的话就替换成-,那么结果应该是ab-d啊、空匹配是什么意思
  3. '-a-b-d-'
复制代码
最佳答案
2018-7-26 19:16:12
小小小小的鱼丶 发表于 2018-7-26 18:45
弱弱的问一句。。能再详细些吗。。。就是使用sub('-',abxd)的时候的替换过程。。有点愚钝

p = re.compile('x*')
p.sub('-','abxd')
'-a-b-d-'
-----------------------------------------------------
上面是代码
首先是传入正则表达式'x*’构建了一个对象p,
然后以'x*'作为匹配式来匹配 abxd 这个字符串,如果匹配到内容就替换为 -
'x*' 可以匹配到的 内容为 '' 和 x 这两个
(这个时候你要先明白我之前说的
*        匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。)的意思。
对abxd进行匹配。
1。a不满足匹配式,但a前面的 '' 满足,首先返回 '' 得到 ['']    (这时候替换成了 -a )
2。b不满足匹配式,但b前面的 '' 满足,继续返回 '' 得到 ['',''] (加1步这时候替换成了 -a-b)
3。x满足匹配式,继续返回得到 ['','','x'] (加上前两步替换撑了-a-b-)
4。d不满足匹配式,但因为前面已经匹配到了x所以直接匹配最后又一个 '' 这样就得到了['','','x',''] 最后就变成了-a-b-d-
如果这样都还不明白,你可以去下一个pycharm或者eclipse断点查看执行顺序和执行结果
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-7-26 14:35:03 | 显示全部楼层
因为findall的结果:
  1. >>> re.findall('x*','abxd')
  2. ['', '', 'x', '', '']
  3. >>>
复制代码

然后根据findall的匹配到的位置来进行替换。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 16:11:20 | 显示全部楼层
无符号整形 发表于 2018-7-26 14:35
因为findall的结果:

然后根据findall的匹配到的位置来进行替换。

没咋懂,我调用的是sub方法,没有调用findall方法呀。而且就算是re.findall('x*','abxd')
那么返回的不应该是【' ',' ','x',' '】嘛,您好像多写了一个?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 16:17:20 | 显示全部楼层
小小小小的鱼丶 发表于 2018-7-26 16:11
没咋懂,我调用的是sub方法,没有调用findall方法呀。而且就算是re.findall('x*','abxd')
那么返回的不 ...

sub方法基于findall方法,另外可能是我们的idle版本不同吧。
毕竟你不找出全部怎么替换啊。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 16:35:42 | 显示全部楼层
本帖最后由 小小小小的鱼丶 于 2018-7-26 16:39 编辑
无符号整形 发表于 2018-7-26 16:17
sub方法基于findall方法,另外可能是我们的idle版本不同吧。
毕竟你不找出全部怎么替换啊。。


我试了一下re.findall('x*','abxd')返回的[' ', ' ', 'x', ' ', ' '] 但是不应该匹配到d的时候,发现字符串到了末尾就结束了嘛,为什么还会向下再匹配一个
还有这个匹配过程。没看懂。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 16:42:28 | 显示全部楼层
小小小小的鱼丶 发表于 2018-7-26 16:35
我试了一下re.findall('x*','abxd')返回的[' ', ' ', 'x', ' ', ' '] 但是不应该匹配到d的时候,发现字 ...

注意呀,这不是空格呀。。是“什么都没有”啊!!
abxd = "空a空b空x空d空"
首先把第一个空换成"-",
接着把第二个空换成"-"
接着把第三个空换成"-"
然后把第四个x+空换成"-"
最后把第五个空换成"-"
所以得出'-a-b-d-'。

点评

匹配不到就返回 ''  发表于 2018-7-26 17:08
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 16:53:40 | 显示全部楼层
无符号整形 发表于 2018-7-26 16:42
注意呀,这不是空格呀。。是“什么都没有”啊!!
abxd = "空a空b空x空d空"
首先把第一个空换成"-",

有点懵。。正则表达式x*的意思去匹配字符串里面的一到多个x,findall是找到正则表达式匹配的所有位置,并以列表的形式返回,那么不应该返回的只有【x】嘛。 还有如果是匹配不到返回空的话,那么abxd为什么等于"空a空b空x空d空,abxd不就是abxd嘛。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 16:55:24 | 显示全部楼层
因为x*表示匹配x零次或多次,匹配零次得到四个'',匹配一次得到一个'x',所以出现了楼主的结果
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 17:02:53 | 显示全部楼层
fqaipy 发表于 2018-7-26 16:55
因为x*表示匹配x零次或多次,匹配零次得到四个'',匹配一次得到一个'x',所以出现了楼主的结果

呃呃,懂了。但是sub的时候,为什么是那样匹配的呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 17:05:42 | 显示全部楼层
小小小小的鱼丶 发表于 2018-7-26 17:02
呃呃,懂了。但是sub的时候,为什么是那样匹配的呢

呃,你不全部找出来,能替换么。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 17:13:09 | 显示全部楼层
无符号整形 发表于 2018-7-26 17:05
呃,你不全部找出来,能替换么。。

我没明白他是怎么进行匹配的。。find找到的是【空,空,x ,空,空】
那么p.sub('-',abxd),abxd是根据什么原理成为了空a空bx空d空。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 17:14:32 | 显示全部楼层
fqaipy 发表于 2018-7-26 16:55
因为x*表示匹配x零次或多次,匹配零次得到四个'',匹配一次得到一个'x',所以出现了楼主的结果

额,我感觉这个逻辑不通。按你这么说,匹配x2次也是4个空啊。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 17:14:38 | 显示全部楼层
小小小小的鱼丶 发表于 2018-7-26 17:13
我没明白他是怎么进行匹配的。。find找到的是【空,空,x ,空,空】
那么p.sub('-',abxd),abxd是根据什 ...
  1. p = re.compile('x*')
复制代码
->你编译了一个表达式(通俗点说就是创建了一个表达式对象)
相当于:
  1. re.sub('x*','-','abxd')
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 17:45:41 | 显示全部楼层
*        匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。

这是官方给出的正则表达式中 * 的用法。

楼主看到 zo* 为什么能匹配到  z 肯定有疑惑。
他难道不应该匹配到最短的字符就应该是 zo 吗?

其实我在之前都没注意到这一点。
然后我去试了试几个字符串的匹配

re.findall('x*','x')
返回的结果是 ['x','']
楼主看到没,这个地方为什么会多出    ‘’   ?
如果楼主仔细看,就会发现,官方给出的 zo*
re.findall('zo*','z') 得到的结果就是 z
re.findall('zoo*','zo')得到的结果就是 zo
于是我在这里得到的理解就是,
对于*这个匹配字符来说,匹配的结果就是  要匹配的表达式的的全部或除去*之前的一个字符
(可能表达不清楚,我也不知道怎么说才表达正确,官方给的文档是最好的)

正如之前有人回答sub是基于findall的,这个说法是正确的
所以 x* 可以匹配到 ‘’  和 x  这里的 ‘’ 不是中间有个空格,而是没有任何东西的意思
所以 re.findall('x*','abxd') 匹配的结果就是 ['',a,'',b,'x',d,'']所以
替换后结果就是 -a-b-d-

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 17:47:21 | 显示全部楼层
ErTian 发表于 2018-7-26 17:45
*        匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。

这是官方给出的正 ...

补充一点。当*前面没有任何匹配的字符,即表示通用匹配符,(任何都可以匹配到)
如果 * 前面有字符 则表示限定符( 即官方给出的意思  
*        匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 18:02:06 | 显示全部楼层
ErTian 发表于 2018-7-26 17:45
*        匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。

这是官方给出的正 ...

额。比较不理解的地方就是为啥findall返回的是 ['',a,'',b,'x',d,''],我用python返回的是['', '', 'x', '', '']。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 18:04:07 | 显示全部楼层
无符号整形 发表于 2018-7-26 17:14
->你编译了一个表达式(通俗点说就是创建了一个表达式对象)
相当于:

这个我懂。就是不能理解,findall的返回值是['', '', 'x', '', ''],那么sub(-,'abxd')是怎么替换的。为什么字符串最后扩展了,是将返回值与abxd合并再去替换嘛
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 18:35:40 | 显示全部楼层
小小小小的鱼丶 发表于 2018-7-26 18:02
额。比较不理解的地方就是为啥findall返回的是 ['',a,'',b,'x',d,''],我用python返回的是['', '', 'x',  ...

不好意思,我打错,是该返回['', '', 'x', '', '']
我打成了该替换的位置的,
返回的是['', '', 'x', '', '']。
因为abxd。a不满足匹配条件同时前面相当于一个‘’,所以先返回了 ‘’ 然后接着 b和a同理返回 ’‘ 到x,因为x是满足条件的 所以 返回了’x' 接者,d不满足,同理ab,返回‘’ d后面还有‘’所以又返回了‘’。所以结合起来就是返回['', '', 'x', '', '']
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-26 18:38:13 | 显示全部楼层
ErTian 发表于 2018-7-26 18:35
不好意思,我打错,是该返回['', '', 'x', '', '']
我打成了该替换的位置的,
返回的是['', '', 'x', ' ...

你说的扩展的原因,也就是我说的d后面还有一个 ‘’,所以返回了‘’被替换了。
和用 x*去匹配空内容返回的 ‘’ 是一个道理
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-26 18:45:16 | 显示全部楼层
ErTian 发表于 2018-7-26 18:38
你说的扩展的原因,也就是我说的d后面还有一个 ‘’,所以返回了‘’被替换了。
和用 x*去匹配空内容返回 ...

弱弱的问一句。。能再详细些吗。。。就是使用sub('-',abxd)的时候的替换过程。。有点愚钝
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-10-21 03:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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