【问题标题】:Findall vs search for overwriting groups in PythonFindall vs 在Python中搜索覆盖组
【发布时间】:2016-06-03 16:56:18
【问题描述】:

我找到了主题 Capturing group with findall?,但不幸的是它更基础,只涵盖不覆盖自身的组。

请看下面的例子:

S = "abcabc"  # string used for all the cases below

1。 Findall - 没有组

print re.findall(r"abc", S) # ['abc', 'abc']

总体思路:这里没有组,所以我希望findall 返回所有匹配项的列表 - 请确认。

在这种情况下:Findall 正在寻找 abc,找到它,返回它,然后继续找到第二个。

2。 Findall - 一个明确的组

print re.findall(r"(abc)", S) # ['abc', 'abc']

总体思路:这里有一些群组,所以我希望findall 返回所有群组的列表 - 请确认。

在这种情况下:为什么只有一组结果却有两个结果?我是这样理解的:

  • findall正在寻找abc

  • 找到了,

  • 将其放在组内存缓冲区中,

  • 返回,

  • findall 开始再次寻找abc,以此类推...

这个推理正确吗?

3。 Findall - 覆盖组

print re.findall(r"(abc)+", S) # ['abc']

这看起来与上面类似,但只返回一个abc。我是这样理解的:

  • findall正在寻找abc

  • 找到了,

  • 将其放在组内存缓冲区中,

  • 返回它,因为 RE 本身需要继续,

  • 找到另一个abc

  • 将其放入组内存缓冲区(覆盖之前的abc),

  • 字符串结束,所以搜索也结束。

这个推理正确吗?我在这里非常具体,所以如果有任何问题(即使是微小的细节),请告诉我。

4。搜索 - 覆盖组

Search 扫描字符串以寻找单个匹配项,因此 re.search(r"(abc)", S)re.search(r"(abc)", S) 显然只返回一个 abc,然后让我直接说:

re.search(r"(abc)+", S)
print m.group()  # abcabc
print m.groups() # ('abc',)

a) 当然整场比赛是abcabc,但我们这里还有组,所以我可以得出结论,组与m.group() 无关(尽管有名称)?这就是为什么此方法不会覆盖任何内容?

事实上,括号的这种分组功能在这里是完全没有必要的——在这种情况下,我只想用括号来强调在不创建任何正则表达式组的情况下重复事物时需要放在一起的内容。

b) 谁能像我在项目符号 3 中所做的那样解释返回 abcabc(就缓冲区等而言)背后的机制?

【问题讨论】:

  • 为什么不先完成上一题呢?您那里有 2 个答案,但您没有提供任何反馈。
  • 我了解您有一些问题,没关系。但是在本网站的工作方式中,最好将每个问题分开,以便问题的答案可以是完整的,而不是部分的。正则表达式模块的文档中也涵盖了很多您所问的内容,并且很难准确理解您要问的问题,我建议您先做一些研究,也许您的问题已经有了答案,否则,请拆分您的提出问题,并为每个问题提供足够的信息以使其独立。您需要帮助的代码的最小工作示例。
  • @Wiktor,我的目的是先了解小组如何在 Python 中工作,然后再回到上一个主题,因为我必须承认您和其他人的答案对我来说并不完全清楚。我想知道在哪里提出我的问题,但最终决定最好将它们分开而不是使之前的主题太长。你的回答让我意识到我需要一些初步的知识来理解它,我在这里问了这个问题。如果它错了,我可以把它放在那里,但我无法想象它如何更具可读性......
  • @Inbar,我是这个网站的新手,所以每一个反馈都非常感谢 - 谢谢!但是,我不知道我怎么能把这么长的陈述放在前面的话题中。也许我只是错误地在这里提到了上一个主题,因为这两个主题是真正分开的。我将删除引用它的开头。
  • @Drizzt 你只需要意识到这是一个问答网站。不是论坛。提出问题,得到答案。但是你一次问很多问题,这对我们的格式不利。此外,您提出的问题并不是最适合本网站。我建议你先自己研究一下文档,以及如何使用这个网站,并提出问题,有一个很棒的 help centerHow to Ask 指南。

标签: python regex


【解决方案1】:

首先,让我陈述一些事实:

  • 匹配值 (match.group()) 是符合正则表达式中定义的整个模式的(子)文本。匹配可以包含零个或多个捕获组
  • 捕获值 (match.group(1..n)) 是与带括号的模式部分(包含在一对未转义括号中的模式的一部分)。
  • 某些语言可以提供对捕获集合的访问,即所有使用量化捕获组(如(\w{3})+)捕获的值。在 Python 中,可以使用 PyPi regex module,在 .NET 中,使用 CaptureCollection 等。

1:这里没有组,所以我希望 findall 返回所有匹配项的列表 - 请确认。

  • 是的,仅当模式中定义了捕获组时,re.findall 才会返回捕获的子匹配列表。对于abcre.findall 返回匹配列表。

2:为什么只有一组结果却有两个结果?

  • 有两个匹配项,re.findall(r"(abc)", S)abcabc 中找到两个匹配项,并且每个匹配项都有一个子匹配项,或捕获的子字符串,因此生成的数组有 2 个元素(abcabc)。

3:这个推理正确吗?

  • re.findall(r"(abc)+", S) 正在寻找abcabcabc 等形式的匹配项。它将作为一个整体进行匹配,并将最后一个 abc 保留在捕获组 1 缓冲区中。所以,我认为你的推理是正确的。 RE 本身要求继续可以精确为因为匹配尚未完成(因为仍有字符供正则表达式引擎测试匹配)。李>

4:整场比赛是abcabc,但我们这里还有分组,所以我可以断定分组与m.group() 无关(尽管有名称)?

  • 不,在这种情况下保留最后一个组值。如果您将您的正则表达式更改为(\w{3})+ 并将字符串更改为abcedf,您将感受到不同之处,因为该案例的输出将为edf这就是为什么此方法不会覆盖任何内容? - 所以,你错了,前面的捕获组值 被以下值覆盖。

5:谁能像我在第 3 条中所做的那样解释返回 abcabc(就缓冲区等而言)背后的机制?

re.search(r"(abc)+", S) 将匹配 abcabc匹配,而不是捕获)因为

  1. abcabc 从左到右搜索 abc。 RE 在开头找到abc,并尝试从第一个c 之后的位置找到另一个abc。 RE 将 abc 放入捕获组缓冲区 1。
  2. RE 找到第二个abc,用它重写捕获组#1 缓冲区。试图找到另一个abc
  3. 找不到更多abc - 返回找到的匹配值:abcabc

【讨论】:

  • 感谢您的帮助,现在我几乎完全清楚了。如果我可以再问你两个更明确的问题:1) 我问 “我能否得出结论,组与 m.group() 无关(尽管有名称)?” 而你回答 “否” ,但是看看你对 5 的解释,你说:a)组被覆盖,这当然对m.groups() 方法有影响 - capture value,b)整个比赛是仍然是abcabc,所以我猜这个覆盖对m.group() 方法没有影响-match value。那么组覆盖与m.group() 方法无关的说法是真的吗?
  • 2) 关于2,你说的“每个匹配有一个子匹配,或捕获的子字符串”是什么意思??这是否意味着我们有两个匹配 abcabc,同时它们使 (abc)(abc) 捕获组?这是我的理解,在这个项目符号中,我想知道为什么第二个捕获的组没有覆盖第一个,我得出的结论是,第一组是由 findall 早些时候返回的。是真的吗?
  • 1) 我了解 组覆盖无关 group() (=group(0)) 作为组子值覆盖没有发生。不意味着这是错误的,任何与后续相邻子字符串匹配的量化捕获组都会发生覆盖。 2)r"(abc)" 模式匹配abcabc 中的 2 个后续 abcabc(第一次匹配,1 次捕获)+abc(第二次匹配,1 次捕获)。这里没有量化的捕获组,因此,没有发生“覆盖”。
  • ad 1) 好吧,我想我们的意思是一样的,我只是不知道合适的术语,所以我用不同的、不那么正式的方式来表达。就像您建议的示例一样:re.search(r"(\w{3})+", "abcdef"),覆盖发生在这里,所以groups() 返回def,但是group(),没有任何数字,仍然返回abcdef - 正如你在谈到match value 时所解释的那样 -这不受def 覆盖abc 的影响。那就解决了。
  • 我明白了,我同意 Python re 方法 m.group()m.groups() 有点误导。在 .NET 中,这听起来不那么模棱两可:match.Value 而不是 m.Groups。至于 2),Python 命名同样具有误导性。 r"(abc)" 不能进行覆盖,因为整个匹配 abc 保存在 m.group() (=m.group(0)) 中,而捕获组文本 abc 保存在 m.group(1) 中。如果在) 之后存在量词,则会覆盖捕获组 1。 group()是一个匹配值group(1)是第一个捕获组值。跨度>
猜你喜欢
  • 1970-01-01
  • 2012-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-27
相关资源
最近更新 更多