re.findall提供的结果与re.search具有相同模式的结果不同

时间:2018-09-25 14:11:01

标签: python regex

我想把子字符串放在单引号(')中:

line = "This is a 'car' which has a 'person' in it!"

所以我用过:

name = re.findall("\'(.+?)\'", line)
print(name[0])
print(name[1])
  

汽车
  人

但是当我尝试这种方法时:

pattern = re.compile("\'(.+?)\'")
matches = re.search(pattern, line)
print(matches.group(0))
print(matches.group(1))
# print(matches.group(2))  # <- this produces an error of course
  

'汽车'
  汽车

所以,我的问题是为什么模式在每种情况下的行为都不同?我知道前者返回“字符串中模式的所有非重叠匹配”,而后者返回对象,这可能解释了一些差异,但是我希望在相同模式下结果相同(即使格式不同)。

因此,要更具体一点:

  1. 在第一种情况下使用findall的模式返回所有子字符串,但在后一种情况下,其仅返回第一个子字符串。
  2. 在后一种情况下,matches.group(0)(根据文档对应于the whole match)与matches.group(1)(对应于第一个带括号的子组)不同。为什么会这样?

re.finditer("\'(.+?)\'", line)返回匹配对象,因此其功能类似于re.search

我知道也有类似的问题,例如oneone,但是他们似乎并没有回答原因(或者至少我没有理解)。

2 个答案:

答案 0 :(得分:2)

您已经阅读了文档和其他答案,所以我将为您提供动手的说明

让我们首先以here

为例
>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0)       # The entire match
'Isaac Newton'
>>> m.group(1)       # The first parenthesized subgroup.
'Isaac'
>>> m.group(2)       # The second parenthesized subgroup.
'Newton'
>>> m.group(1, 2)    # Multiple arguments give us a tuple.
('Isaac', 'Newton')

如果继续进行this website,您将找到与先前检测到的对应关系

first example

group(0)正在完全匹配,图中的group(1)和group(2)分别是Group 1和Group 2。正如here所说,“ Match.group([group1,...]) 返回匹配项的一个或多个子组。如果有单个参数,则结果为单个字符串;如果有多个参数,则结果是一个元组,每个参数有一个项目。没有参数,group1默认为零(将返回整个匹配项)“

现在让我们回到您的示例

second example

正如其他使用re.search(pattern, line)的人所说,您只会发现模式的第一次出现[如here所述:“扫描字符串以查找正则表达式模式产生匹配项的第一个位置”]并按照前面的逻辑,您现在将了解为什么matches.group(0)将输出完全匹配并{1}}组1。并且您将了解matches.group(1)为什么会给您错误[因为您可以看到从屏幕截图中可以看出,在最后一个示例中,第一个没有出现第2组]

答案 1 :(得分:1)

  1. re.findall返回匹配的列表(在此示例中,第一组匹配),而re.search返回 仅第一个最左边的匹配项。

    如python文档(re.findall)中所述:

      

    返回全部不重叠   字符串中的模式匹配项,为字符串列表。字符串是   从左到右扫描,并以找到的顺序返回匹配项。如果   模式中存在一个或多个组,返回一个列表   组;如果模式有多个,则这将是一个元组列表   组。空匹配项包含在结果中。

  2. matches.group(0)为您提供与模式匹配的字符串的整个片段,这就是为什么要加引号的原因,而matches.group(1)为您提供第一个带括号的子字符串匹配的片段,这意味着它不会包含引号,因为它们在括号之外。查看Match.group()文档以了解更多信息。