鱼C论坛

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

关于正则表达式的问题 我已经被困扰了好几天了

[复制链接]
发表于 2020-7-5 23:21:52 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 shabum 于 2020-7-5 23:27 编辑

print(re.findall(r"\b\w+(?!ing)","cooking ,we ,doing"))    为什么  结果是['cooking', 'we', 'doing']  如果有大佬见到麻烦教导一下。真的感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-7-5 23:22:52 | 显示全部楼层
本帖最后由 shabum 于 2020-7-5 23:27 编辑

(?!ing)  意思不是应该只是匹配到we 吗 ? 为什么全部都匹配到了。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-5 23:48:51 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-6 00:00:24 | 显示全部楼层
re.findall方法

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表(字符串列表,不是匹配对象),如果没有找到匹配的,则返回空列表
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-7-6 00:09:42 | 显示全部楼层
本帖最后由 shabum 于 2020-7-6 00:11 编辑
Hello. 发表于 2020-7-6 00:00
re.findall方法

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表(字符串列表,不是匹配对象 ...


抱歉再打扰一下,如果我想看到他的匹配结果要如何才能看到?我用(?=ing)print(re.findall(r"\b\w+(?=ing)","cooking ,singing ,doing")) 返回的是 ['cook', 'sing', 'do']
为什么 (?!ing) 就不行呢?  主
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-6 00:10:55 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-6 00:16:17 | 显示全部楼层
Hello. 发表于 2020-7-6 00:10
http://c.runoob.com/front-end/854

cooking ,wwe ,doing   我刚刚测试这个文本  表达式是\b\w+(?!ing)   
共找到 3 处匹配:
cooking
wwe
doing
奇怪是 cooking 和doing 都被匹配了。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-6 01:07:52 | 显示全部楼层
shabum 发表于 2020-7-6 00:16
cooking ,wwe ,doing   我刚刚测试这个文本  表达式是\b\w+(?!ing)   
共找到 3 处匹配:
cooking





你不能 用 \w+ 来匹配这些断言的字符,因为 \w+本身就是匹配一次或者多次,而且默认还是贪婪模式

举个例子,假设就是匹配你这里的字符 不匹配带 ing

"cooking ,we ,doing"

那么因为先匹配的是\w+ 所以这个时候 \w+ 因为默认是贪婪,所以会先匹配到 cooking 后面的空格\w+匹配结束,然后判断 cooking 字符串后面是不是 ing ,而 cooking 字符串后面是空格 所以符合条件成功匹配

这样就和我们所想的就不一样,因为 \w+ 默认是一直匹配字母直到遇到其他字符

所以你这里的 ['cooking', 'we', 'doing'] 这个结果完全是 \w+ 匹配的,而且每次一定会把连续的英文字母匹配进去,所以肯定会满足 (?!ing) 断言,即始终满足字符后面不是 ing

再举个例子吧,这种感情确实有点拗口:

  1. import re
  2. s = "cooking ,we ,doing"
  3. print(re.findall(r"\w{2}(?!ing)",s))
复制代码


这个代码的运行结果:
  1. ['co', 'ki', 'ng', 'we', 'oi', 'ng']
复制代码


有没发现,我们没有匹配到 ok 字符,就是因为我们是设置 (?!ing) , 当我们 \w 匹配两次到 ok 的时候判断了 (?!ing) 导致不匹配 ok,而匹配到 ki 的时候 后面的字符串是 'ng ' 而不是 ing 所以成功匹配


你好好理解理解,就是 \w+ 的问题,你如果直接明确是什么,那就好多了:
  1. import re
  2. s = "coweing ,we ,weing"
  3. print(re.findall(r"we(?!ing)",s))
复制代码

输出结果:
  1. ['we']  # 这里的 weing 就没有成功匹配出来
复制代码





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

使用道具 举报

 楼主| 发表于 2020-7-6 13:00:10 | 显示全部楼层
本帖最后由 shabum 于 2020-7-6 13:01 编辑
Twilight6 发表于 2020-7-6 01:07
你不能 用 \w+ 来匹配这些断言的字符,因为 \w+本身就是匹配一次或者多次,而且默认还是贪婪模式 ...


谢谢你解答了我这个问题,但是我这边还几个疑惑
一个是关于\w+(?=ing)  当我匹配的cooking singing 时候 他返回的匹配是cook 和sing  如果按照你上面的
说法那样会有点不太对的感觉 因为\w+理论应该像上面直接包含了cooing singing 这样的情况  
我看到网上说  先从要匹配的字符串中的最右端找到第一个 ing (也就是先行断言中的表达式)然后 再匹配其前面的表达式,若无法匹配则继续查找第二个 ing 再匹配第二个 ing 前面的字符串,若能匹配则匹配,符合正则的贪婪性。
请问这个没错吗?也就是\w+(?=ing)的时候是从字符串最右边先匹配(?=ing) 再向左边匹配\w+?

而(?<=ing).* 他 我测试发现  他匹配cooking singing 的时候 返回是空格singing和上面的?!一样的过程

而(?<!ing).*  匹配的是cooking singing  那么是不是代表匹配的时候 首先从字符串最右边执行的 .*
到第一个字符串c后就再判断 (?<!ing)   ?   麻烦大佬确认下 是不是这样的? 就差最后这点了



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

使用道具 举报

发表于 2020-7-6 13:27:33 | 显示全部楼层
shabum 发表于 2020-7-6 13:00
谢谢你解答了我这个问题,但是我这边还几个疑惑
一个是关于\w+(?=ing)  当我匹配的cooking  ...




不用客气哈~我描述确实有误哈,那在来重新分析下吧:

"cooking ,we ,doing"

我们来匹配 re.findall(r"\w+(?!ing)"  是字符串后面不等于 ing,当我们\w+匹配到 cook 的时候 发现 cook 后面字符串是等于 ing 的所以没有将 cook 字符匹配成功

而因为是贪婪所以 \w+ 可以继续匹配,匹配到 cooking 的时候 后面的字符不是 ing ,所以成功匹配,放入列表

doing 也是同理,匹配到 do 时候 因为 do 后面字符串是 ing 所以 do 被过滤,而\w+贪婪,所以继续匹配到结尾后,发现后面字符串不是 ing 所以 成功匹配

而你说的  : 先从要匹配的字符串中的最右端 ,应该是正确的,因为我并不了解正则,昨天晚上也是写出自己的理解哈~



而(?<=ing).* 他 我测试发现  他匹配cooking singing 的时候 返回是空格singing和上面的?!一样的过程

我觉得上面的能阐述这个问题嘿嘿,你看看上面的例子~

而(?<!ing).*  匹配的是cooking singing  那么是不是代表匹配的时候 首先从字符串最右边执行的 .*

感觉是因为贪婪的原因吧...但是我也不敢确定,我的正则还是需要好好学习,抱歉帮不了你了


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

使用道具 举报

 楼主| 发表于 2020-7-7 00:44:21 | 显示全部楼层
Twilight6 发表于 2020-7-6 13:27
不用客气哈~我描述确实有误哈,那在来重新分析下吧:

"cooking ,we ,doing"

我测试过几次了
得出结论
(?=exp):无论看正则表达式还是字符串检索都是从“右”开始看
(?!exp):无论看正则表达式还是字符串检索都是从“左”开始看
(?<=exp):无论看正则表达式还是字符串检索都是从“左”开始看
(?<!exp):无论看正则表达式还是字符串检索都是从“右”开始看   
如果没你提醒 我真的看不出 谢谢啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-7 05:46:23 | 显示全部楼层
shabum 发表于 2020-7-7 00:44
我测试过几次了
得出结论
(?=exp):无论看正则表达式还是字符串检索都是从“右”开始看



哈哈  我也学习到了,谢谢,如果可以不妨设置个最佳吧~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-20 11:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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