【问题标题】:re.findall gives different results than re.search with the same patternre.findall 给出的结果与具有相同模式的 re.search 不同
【发布时间】:2019-03-01 04:50:31
【问题描述】:

我有 str ,我想在单引号内获取子字符串 ('):

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 但他们似乎没有回答为什么(或者至少我没有得到它)​​。

【问题讨论】:

  • 你至少明白re.search 只找到第一个匹配项吗?
  • 根据manual扫描字符串,寻找正则表达式模式产生匹配的第一个位置
  • re.group(0) 指的是超群。
  • 另外finditer应该在循环中使用。

标签: python regex


【解决方案1】:

你已经阅读了文档和其他答案,所以我会给你一个动手解释

我们先从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你会发现与之前检测的对应关系

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

现在让我们回到你的例子

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

【讨论】:

    【解决方案2】:
    1. re.findall 返回 list 匹配项(在此特定示例中,第一组匹配项),而 re.search 返回 只有第一个最左边的匹配。

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-01-13
      • 1970-01-01
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多