Python 芬德尔的行为很怪异
源字符串为:Python 芬德尔的行为很怪异,python,regex,Python,Regex,源字符串为: # 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'>
# 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
给我期望的列表:
['123', '3.1415926']
这里有两件事需要注意:
如果正则表达式模式中包含捕获组,则返回捕获的文本re.findall
- 模式中的
部分匹配两个连续字符,r'\\.
和除换行符以外的任何字符\
re.findall
仅返回匹配值,通常可以
- 删除冗余捕获组(例如
->(a(b)c)
)abc
- 将所有捕获组转换为(即,用
)替换(?:
),除非有反向引用引用模式中的组值(请参见下文)(
- 改用
(re.finditer
)[x.group()表示re.finditer(模式,s)中的x)]
findall
返回了所有捕获的文本,这些文本都是空的,因为您在r'
中有\
字符串文本试图匹配文本\
要匹配这些数字,您需要使用
-?\d*\.?\d+
正则表达式匹配:
-可选减号-?
-可选数字\d*
-可选的十进制分隔符\.?
-1个或多个数字\d+
['123',3.1415926']
此外,返回类型将是一个字符串列表。如果希望返回类型为整数和浮动,请使用映射
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]
只是为了解释为什么您认为search
返回了您想要的而findall
没有返回
搜索返回包含以下信息的SRE_Match
对象:
:属性包含传递给搜索函数的字符串string
:re
搜索函数中使用的对象REGEX
:由groups()
REGEX中的捕获组捕获的字符串列表
:使用group(index)
按组检索捕获的字符串index>0
:返回与组(0)
正则表达式匹配的字符串
search
在找到第一个马赫数构建SRE_Match
对象并返回时停止,请检查此代码:
重新导入
s=r'abc123d'
模式=r'-?[0-9]+(\[0-9]*)?\-?\[0-9]+'
m=重新搜索(模式,s)
打印(m.string)#“abc123d”
打印(m.group(0))#正则表达式匹配123
print(m.groups())#正则表达式中只有一个组(\.[0-9]*)将empy字符串,这就是它返回(无)的原因
s=',你好3.1415926,这是我的书'
m2=re.search(pattern,s)#',您好3.1415926,这是我的书
打印(m2.string)#abc123d
打印(m2.组(0))#正则表达式匹配3.1415926
打印(m2.groups())#捕获的组已捕获此部分“.1415926”
findall
的行为有所不同,因为它不会在找到第一个马赫数时停止提取,直到文本结束,但如果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']
当发现第一个马赫数时,第一个元素
返回,该马赫数为'123'
捕获组仅捕获'
,但第二个元素
在第二次匹配'3.1415926'
中捕获,捕获组匹配此零件'.1415926'
如果要使findall
返回匹配字符串,则应将正则表达式中的所有捕获组()
设置为非捕获组(?:)
:
将捕获组转换为非捕获组。@AvinashRaj,嗯..,如果我删除了该捕获组,即使重新搜索也会给我一个“无”result@stribizhev,它不是,'3.1415926'应该是result@O“天行者尝试使用puttern之类的-?\d?\。?\d+一些在线网站可以帮助调试,例如,尽管此正则表达式的效率不如其他正则表达式我的,我承认ast
的技巧很酷(虽然在OP中不是必需的)。@Stribizev我读了他的一条评论……@Stribizev,不是,'3.1415926'应该是结果中的浮点数
,所以我在回答中包括了这一点:)你们两个都是天才,我很难选择接受哪一个。:)@O'Skywalker一点也不像天才:P…………只要练习……你很快就会成为一名非洲裔!!!!!!!!您还可以使用如下第一个字符区分来减少步骤:(?=[-\d.])-(?:\d+(?:\。\d*)?\124;\。\ d+)
s = r'abc123d, hello 3.1415926, this is my book'
print re.findall(r'-?[0-9]+(?:\.[0-9]*)?|-?\.[0-9]+',s)
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))
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']
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']