关于正则表达式的问题 我已经被困扰了好几天了
本帖最后由 shabum 于 2020-7-5 23:27 编辑print(re.findall(r"\b\w+(?!ing)","cooking ,we ,doing")) 为什么结果是['cooking', 'we', 'doing']如果有大佬见到麻烦教导一下。真的感谢{:10_266:} 本帖最后由 shabum 于 2020-7-5 23:27 编辑
(?!ing)意思不是应该只是匹配到we 吗 ? 为什么全部都匹配到了。。。 https://www.cnblogs.com/fengf233/p/11076870.html re.findall方法
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表(字符串列表,不是匹配对象),如果没有找到匹配的,则返回空列表 本帖最后由 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) 就不行呢?主 http://c.runoob.com/front-end/854 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 都被匹配了。。{:10_266:} 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
再举个例子吧,这种感情确实有点拗口:
import re
s = "cooking ,we ,doing"
print(re.findall(r"\w{2}(?!ing)",s))
这个代码的运行结果:
['co', 'ki', 'ng', 'we', 'oi', 'ng']
有没发现,我们没有匹配到 ok 字符,就是因为我们是设置 (?!ing) , 当我们 \w 匹配两次到 ok 的时候判断了 (?!ing) 导致不匹配 ok,而匹配到 ki 的时候 后面的字符串是 'ng ' 而不是 ing 所以成功匹配
你好好理解理解,就是 \w+ 的问题,你如果直接明确是什么,那就好多了:
import re
s = "coweing ,we ,weing"
print(re.findall(r"we(?!ing)",s))
输出结果:
['we']# 这里的 weing 就没有成功匹配出来
本帖最后由 shabum 于 2020-7-6 13:01 编辑
Twilight6 发表于 2020-7-6 01:07
你不能 用 \w+ 来匹配这些断言的字符,因为 \w+本身就是匹配一次或者多次,而且默认还是贪婪模式 ...
谢谢你解答了我这个问题,但是我这边还几个疑惑{:10_266:}
一个是关于\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) ? {:10_266:}{:10_285:}麻烦大佬确认下 是不是这样的? 就差最后这点了
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那么是不是代表匹配的时候 首先从字符串最右边执行的 .*
感觉是因为贪婪的原因吧...但是我也不敢确定,我的正则还是需要好好学习,抱歉帮不了你了
Twilight6 发表于 2020-7-6 13:27
不用客气哈~我描述确实有误哈,那在来重新分析下吧:
"cooking ,we ,doing"
我测试过几次了
得出结论
(?=exp):无论看正则表达式还是字符串检索都是从“右”开始看
(?!exp):无论看正则表达式还是字符串检索都是从“左”开始看
(?<=exp):无论看正则表达式还是字符串检索都是从“左”开始看
(?<!exp):无论看正则表达式还是字符串检索都是从“右”开始看
如果没你提醒 我真的看不出 谢谢啦{:10_266:} shabum 发表于 2020-7-7 00:44
我测试过几次了
得出结论
(?=exp):无论看正则表达式还是字符串检索都是从“右”开始看
哈哈我也学习到了,谢谢,如果可以不妨设置个最佳吧~
页:
[1]