【问题标题】:Why Does a Repeated Capture Group Return these Strings?为什么重复捕获组返回这些字符串?
【发布时间】:2014-07-21 02:40:42
【问题描述】:

有人可以解释为什么以下返回“cc”吗?

>>> re.match('(..)+', 'aabbcc').group(1)
'cc'

有人告诉我,因为它把每场比赛都放到了 group(1) 中,所以最后一场比赛是 'cc'。这是真的吗?

那接下来怎么解释呢?

>>> re.match('(..)+(...)', 'aabbcc').group(1)
'aa'

【问题讨论】:

    标签: python regex


    【解决方案1】:

    重复捕获组:组号保持不变

    (..) 定义的组是组 1。+ 量词重复它。每次引擎能够重复组(匹配两个字符)时,组 1 都会被覆盖。

    • 当引擎开始匹配时,它会将aa 捕获到第 1 组
    • 然后它将bb 捕获到第 1 组
    • 然后它将cc 捕获到第1 组。

    当您检查第 1 组时,引擎会返回 cc。所有其他捕获都将丢失。

    (例外是 .NET 引擎,它也返回 cc,但由于 CaptureCollection 对象,它还允许您检查中间捕获。它将包含 aabbcc。)

    使用(..)+(...),为什么第1组包含aa?回溯!

    为了理解这一点,我们再次需要遵循正则表达式引擎的路径。

    • 再次,当引擎开始匹配时,它会将aa 捕获到第 1 组
    • 同样,它重复(..) 组并将bb 捕获到第1 组
    • 再次,它重复(..) 组并将cc 捕获到组1
    • 引擎现在尝试匹配(...)。它失败了:没有可用的字符了。
    • 引擎在字符串和正则表达式模式中回溯+ 表示一次或多次,我们匹配了.. 三次,所以我们可以放弃一次,甚至两次。在这个阶段,引擎放弃量化的(..)+组的最后一个匹配,即cc。我们回到了第 1 组是 bb 的时候。
    • 引擎再次尝试匹配(...)。只剩下两个字符:cc,所以又失败了。
    • 引擎回溯,放弃量化的(..)+ 组的最后一个匹配项,即bb。在这个阶段,第 1 组又是aa
    • 引擎再次尝试匹配(...)。成功:第 2 组为bbc,第 1 组为aa

    参考

    【讨论】:

    • 仅供参考,我为(..)+(...) 案例添加了引擎内部的详细说明。还强烈建议您阅读链接的“血腥细节”文章。 :)
    • 决定删除我的,不想写故事了。
    • @hwnd 是的,了解它是如何工作的很有趣,但是正如您所说,您必须编写整个引擎故事。 :)
    • 嘿德清,我添加了很多细节,所以如果有什么不清楚的地方请告诉我。 :)
    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    相关资源
    最近更新 更多