Python正则表达式问号运算符不工作?

时间:2013-01-02 01:26:06

标签: python regex capture optional

import re
str='abc defg'
m1 = re.match(".*(def)?",str)
m2 = re.match(".*(def)",str)
print (m1.group(1),m2.group(1))

以上的输出是:

  

(无,'def')

发生了什么事?即使使用非贪婪的重复运算符,也不会匹配可选的捕获组(def)?

1 个答案:

答案 0 :(得分:13)

以下是正则表达式引擎尝试将.*(def)abc defg匹配时发生的情况:

  • 首先,引擎开始尝试匹配字符串开头的正则表达式。
  • 贪婪的子模式.*最初尝试匹配尽可能多的匹配整个字符串。
  • 由于这会导致匹配的其余部分失败,因此正则表达式引擎会回溯,直到找到匹配(def)的方式,这在.*仅匹配abc 时会发生。< / LI>

但是,如果我们将正则表达式更改为.*(def)?,则会发生以下情况:

  • 首先,正则表达式引擎再次从字符串的开头开始。
  • 接下来,它再次尝试匹配.*尽可能多次匹配整个字符串。
  • 但是那时候,因为正则表达式的所有其余部分都是可选的,所以它找到了整个正则表达式的匹配!由于(def)?是贪婪的,所以引擎 更愿意匹配它,如果可能的话,但它不会回溯早期的子模式只是为了看它是否可以。相反,它只是让.*吞噬整个字符串,不为(def)?留下任何内容。

.*?(def).*?(def)?发生了类似情况:

  • 同样,引擎从字符串的开头开始。
  • ungreedy子模式.*?尝试匹配少数次,即根本不匹配。
  • 此时,(def)无法匹配,但(def)?可以匹配。因此,对于(def),正则表达式引擎必须返回并考虑.*?的更长匹配,直到找到允许完整模式匹配的匹配,而对于(def)?它不必执行那,但事实并非如此。

有关更多信息,请参阅"Combining RE Pieces" section of the Perl regular expressions manual(与Python的“Perl兼容”正则表达式的行为相匹配)。