【发布时间】:2014-07-21 02:40:42
【问题描述】:
有人可以解释为什么以下返回“cc”吗?
>>> re.match('(..)+', 'aabbcc').group(1)
'cc'
有人告诉我,因为它把每场比赛都放到了 group(1) 中,所以最后一场比赛是 'cc'。这是真的吗?
那接下来怎么解释呢?
>>> re.match('(..)+(...)', 'aabbcc').group(1)
'aa'
【问题讨论】:
有人可以解释为什么以下返回“cc”吗?
>>> re.match('(..)+', 'aabbcc').group(1)
'cc'
有人告诉我,因为它把每场比赛都放到了 group(1) 中,所以最后一场比赛是 'cc'。这是真的吗?
那接下来怎么解释呢?
>>> re.match('(..)+(...)', 'aabbcc').group(1)
'aa'
【问题讨论】:
(..) 定义的组是组 1。+ 量词重复它。每次引擎能够重复组(匹配两个字符)时,组 1 都会被覆盖。
aa 捕获到第 1 组bb 捕获到第 1 组cc 捕获到第1 组。当您检查第 1 组时,引擎会返回 cc。所有其他捕获都将丢失。
(例外是 .NET 引擎,它也返回 cc,但由于 CaptureCollection 对象,它还允许您检查中间捕获。它将包含 aa、bb 和 cc。)
使用(..)+(...),为什么第1组包含aa?回溯!
为了理解这一点,我们再次需要遵循正则表达式引擎的路径。
aa 捕获到第 1 组(..) 组并将bb 捕获到第1 组(..) 组并将cc 捕获到组1(...)。它失败了:没有可用的字符了。+ 表示一次或多次,我们匹配了.. 三次,所以我们可以放弃一次,甚至两次。在这个阶段,引擎放弃量化的(..)+组的最后一个匹配,即cc。我们回到了第 1 组是 bb 的时候。(...)。只剩下两个字符:cc,所以又失败了。 (..)+ 组的最后一个匹配项,即bb。在这个阶段,第 1 组又是aa。(...)。成功:第 2 组为bbc,第 1 组为aa
参考
【讨论】:
(..)+(...) 案例添加了引擎内部的详细说明。还强烈建议您阅读链接的“血腥细节”文章。 :)