Findall vs在Python中搜索覆盖组

时间:2016-02-22 10:02:28

标签: python regex

我找到了主题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)任何人都能解释退回abcabc(缓冲区等)背后的机制,就像我在子弹 3 中所做的一样吗?

1 个答案:

答案 0 :(得分: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个元素(abc和{{ 1}})。
  

3:这个推理是否正确?

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

4:整个匹配为abc,但我们仍然在这里有群组,因此我可以得出结论abcabc群组无关紧要(尽管名称)?

  • 不,在这种情况下保留最后一个组值。如果您将正则表达式更改为m.group()并将字符串更改为(\w{3})+,您会感觉到差异,因为该情况的输出将为abcedf这就是为什么这个方法没有被覆盖的原因? - 所以,你错了,前面的捕获组值覆盖了以下的。
  

5:任何人都可以解释一下返回edf(就缓冲区等而言)的机制,就像我在子弹3中那样吗?

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

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