re.findall 行为怪异
- 2024-11-18 08:41:00
- admin 原创
- 12
问题描述:
源字符串是:
# Python 3.4.3
s = r'abc123d, hello 3.1415926, this is my book'
这是我的模式:
pattern = r'-?[0-9]+(\\.[0-9]*)?|-?\\.[0-9]+'
但是,re.search
可以给我正确的结果:
m = re.search(pattern, s)
print(m) # output: <_sre.SRE_Match object; span=(3, 6), match='123'>
re.findall
只需转储一个空列表:
L = re.findall(pattern, s)
print(L) # output: ['', '', '']
为什么不能re.findall
给我预期的清单:
['123', '3.1415926']
解决方案 1:
这里有两点需要注意:
re.findall
如果正则表达式模式包含捕获组,则返回捕获的文本r'\.'
模式中的部分匹配两个连续的字符,以及``除换行符之外的任何字符。
参见findall
参考:
如果模式中存在一个或多个组,则返回一个组列表;如果模式有多个组,则这将是一个元组列表。除非空匹配项触及另一个匹配项的开头,否则结果中将包含空匹配项。
请注意,为了使re.findall
返回值仅匹配,您通常可以
删除多余的捕获组(例如
(a(b)c)
->abc
)将所有捕获组转换为非捕获组(即替换
(
为(?:
),除非有指向模式中的组值的反向引用(然后参见下文)改用
re.finditer
([x.group() for x in re.finditer(pattern, s)]
)
在您的情况下,findall
返回所有捕获的空文本,因为您在字符串文字\
中r''
尝试匹配文字``。
为了匹配数字,您需要使用
-?d*.?d+
正则表达式匹配:
-?
- 可选减号d*
- 可选数字.?
- 可选小数分隔符d+
- 1 位或多位数字。
查看演示
以下是IDEONE 演示:
import re
s = r'abc123d, hello 3.1415926, this is my book'
pattern = r'-?d*.?d+'
L = re.findall(pattern, s)
print(L)
解决方案 2:
s = r'abc123d, hello 3.1415926, this is my book'
print re.findall(r'-?[0-9]+(?:.[0-9]*)?|-?.[0-9]+',s)
当您使用原始模式时,您不需要两次退出。
输出:['123', '3.1415926']
返回类型也是字符串列表。如果希望返回整数和浮点数类型,请使用map
import re,ast
s = r'abc123d, hello 3.1415926, this is my book'
print map(ast.literal_eval,re.findall(r'-?[0-9]+(?:.[0-9]*)?|-?.[0-9]+',s))
输出:[123, 3.1415926]
解决方案 3:
只是为了解释为什么您认为它search
返回了您想要的结果但findall
实际上却没有?
搜索返回一个SRE_Match
包含一些信息的对象,例如:
string
:属性包含传递给搜索函数的字符串。re
:REGEX
搜索功能中使用的对象。groups()
:由 内部的捕获组捕获的字符串列表REGEX
。group(index)
:使用 按组检索捕获的字符串index > 0
。group(0)
:返回匹配的字符串REGEX
。
search
当它找到第一个机器构建SRE_Match
对象并返回它时停止,检查以下代码:
import re
s = r'abc123d'
pattern = r'-?[0-9]+(.[0-9]*)?|-?.[0-9]+'
m = re.search(pattern, s)
print(m.string) # 'abc123d'
print(m.group(0)) # REGEX matched 123
print(m.groups()) # there is only one group in REGEX (.[0-9]*) will empy string tgis why it return (None,)
s = ', hello 3.1415926, this is my book'
m2 = re.search(pattern, s) # ', hello 3.1415926, this is my book'
print(m2.string) # abc123d
print(m2.group(0)) # REGEX matched 3.1415926
print(m2.groups()) # the captured group has captured this part '.1415926'
findall
行为有所不同,因为当它找到第一个 mach 时它不会停止,而是一直提取直到文本末尾,但如果REGEX
包含至少一个捕获组,则findall
不会返回匹配的字符串,而是返回捕获组捕获的字符串:
import re
s = r'abc123d , hello 3.1415926, this is my book'
pattern = r'-?[0-9]+(.[0-9]*)?|-?.[0-9]+'
m = re.findall(pattern, s)
print(m) # ['', '.1415926']
第一个element
是在发现第一个马赫时返回的,其中'123'
捕获组仅被捕获''
,但第二个element
是在第二次比赛中捕获的,'3.1415926'
捕获组匹配了这部分'.1415926'
。
如果您想要返回匹配的字符串,您应该将您findall
所有的捕获组都设为非捕获组:()
`REGEX`(?:)
import re
s = r'abc123d , hello 3.1415926, this is my book'
pattern = r'-?[0-9]+(?:.[0-9]*)?|-?.[0-9]+'
m = re.findall(pattern, s)
print(m) # ['123', '3.1415926']
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件