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*
    -可选数字
  • \.?
    -可选的十进制分隔符
  • \d+
    -1个或多个数字

这是:

使用原始模式时,不需要退出两次

输出:
['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']