找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 3415|回复: 7

[求助] 正则表达式的惰性匹配问题

2

主题

7

帖子

7

积分

贫民

积分
7
kurapica2010 发表于 2022-10-19 14:42:44 | 显示全部楼层 |阅读模式
比如(ab){2,3}?
那么,是惰性匹配没问题,一切正常,字符串'ababababababa'可以输出'abab',
那么接下来问题来了,如果在表达式的?后添加其他字符或数字,比如(ab){2,3}?dd
然后我用字符串'ababababababadd'去匹配,神奇的事情就发生了,惰性模式失效了,变回了贪婪匹配,最后输出的字符串变成了'ababababababadd' ,而不是我预料的‘ababdd’。
我尝试了很多次,只要在?后面添加字符,惰性就失效,不知为何?请大家帮忙解答!谢谢!
回复

使用道具 举报

2

主题

7

帖子

7

积分

贫民

积分
7
kurapica2010  楼主| 发表于 2022-10-19 17:53:04 | 显示全部楼层
我顶~~~~~
回复

使用道具 举报

2

主题

7

帖子

7

积分

贫民

积分
7
kurapica2010  楼主| 发表于 2022-10-20 00:03:22 | 显示全部楼层
没人回复吗
回复 支持 反对

使用道具 举报

1

主题

6

帖子

6

积分

贫民

积分
6
rainbowv 发表于 2022-10-20 11:06:54 | 显示全部楼层
你确认你后面那个能匹配到结果??'ababababababadd'   那里有符合 (ab){2,3}?dd 的??  能不能自己多敲几次代码,看仔细一些?发帖内容都不对!
你这是自己把问题复杂化了,(ab)直接用一个字母替代不就好了,加什么大括号,直接用 .*?不是一样么。。
[i for i in re.finditer('a{1,8}?dd','aaaadd')]
[<re.Match object; span=(0, 6), match='aaaadd'>]
你认为应该出一个  add 才是吧?
换成这样的呢?
[i for i in re.finditer('.*?dd','aaaadd')]
[<re.Match object; span=(0, 6), match='aaaadd'>]
是否应该是匹配dd前一个字符,还是匹配dd前全部的字符?
惰性和贪婪问题,应该是向前的(自左向右),就是不影响到下一个可匹配项的情况下,进行惰性或者贪婪选择,设计一个特例,即可看出:
将间隔字母dd,调整为匹配字母a,就可得到你之前预想的结果。
[i for i in re.finditer('(a{2,8}?a)','aaaaaaaaa')]
[<re.Match object; span=(0, 3), match='aaa'>, <re.Match object; span=(3, 6), match='aaa'>, <re.Match object; span=(6, 9), match='aaa'>]
回复 支持 反对

使用道具 举报

2

主题

7

帖子

7

积分

贫民

积分
7
kurapica2010  楼主| 发表于 2022-10-21 15:09:13 | 显示全部楼层
rainbowv 发表于 2022-10-20 11:06
你确认你后面那个能匹配到结果??'ababababababadd'   那里有符合 (ab){2,3}?dd 的??  能不能自己多 ...

感谢回复!
我只是初学者,你写的太多了,我有点看蒙
我是看着书学的,我的问题其实很简单,比如这个表达式(ab){2,3}?dd,我用字符串“abababdd”去匹配,我认为应该出的结果是'abdd',因为惰性匹配啊,所以应匹配到两个abab,然后再加上后面的dd,不就是ababdd吗?但结果却很奇怪,结果就会自动变成了非惰性匹配,就是结果出来abababdd,我自己用不同条件测试了很多次,都是这样!但如果最后没有任何字符,比如就是光秃秃的(ab){2,3}?,那就没问题了,或者前面加字符,比如用字符串‘ddababab’,匹配出来的结果也符合预期,即'ddabab',就是把字符放在最后不行,我就不太懂这个原理!
回复 支持 反对

使用道具 举报

1

主题

6

帖子

6

积分

贫民

积分
6
rainbowv 发表于 2022-10-21 16:25:50 | 显示全部楼层
kurapica2010 发表于 2022-10-21 15:09
感谢回复!
我只是初学者,你写的太多了,我有点看蒙
我是看着书学的,我的问题其实很简单,比如这个表达 ...

你把你的dd,改为ab,然后再试试。。。
回复 支持 反对

使用道具 举报

2

主题

7

帖子

7

积分

贫民

积分
7
kurapica2010  楼主| 发表于 2022-10-21 17:45:08 | 显示全部楼层
rainbowv 发表于 2022-10-21 16:25
你把你的dd,改为ab,然后再试试。。。

改成ab,惰性肯定生效啊。这个我知道,我就是不能理解,为什么不能在后面添加字符呢?后面一添加,前面的惰性就失效了,照理说,应该匹配出ababdd啊!!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

1

积分

贫民

积分
1
python1986 发表于 2022-10-24 21:36:16 | 显示全部楼层
kurapica2010 发表于 2022-10-21 17:45
改成ab,惰性肯定生效啊。这个我知道,我就是不能理解,为什么不能在后面添加字符呢?后面一添加,前面的 ...

很好理解,不是实现,是它没有匹配成功,abababdd->(ab) {2,3)? dd 虽然是贪婪,但是一直没有匹配到dd,所有继续向后匹配,匹配到dd发现自己吃的太多了,已经没有办法了。
回复 支持 反对

使用道具 举报

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

本版积分规则

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