Python非贪婪的正则表达式并不完全符合我的预期

时间:2014-01-25 11:13:28

标签: python regex greedy regex-greedy non-greedy

string:XXaaaXXbbbXXcccXXdddOO

我希望匹配最小字符串,以'XX'开头以'OO'结尾

所以我写了非贪婪的reg:r'XX。*?OO'

>>> str = 'XXaaaXXbbbXXcccXXdddOO'
>>> re.findall(r'XX.*?OO', str)
['XXaaaXXbbbXXcccXXdddOO']

我以为它会返回 ['XXdddOO'] ,但它太'贪婪'了。

然后我知道我必须弄错,因为上面的限定符将首先匹配'XX',然后显示它'非贪婪'。

但我仍然想知道如何才能直接得到我的结果 ['XXdddOO'] 。任何回复都表示赞赏。

直到现在,关键点实际上不是非贪婪,换句话说,它是关于我眼中的非贪婪:它应该在左限定符(XX)和左边限定符之间匹配尽可能少的字符右限定词(OO)。 当然,事实是字符串是从左到右处理的。

4 个答案:

答案 0 :(得分:4)

怎么样:

.*(XX.*?OO)

比赛将在第1组。

答案 1 :(得分:1)

正则表达式从左到右工作:非贪婪意味着它将匹配XXaaaXXdddOO而不是XXaaaXXdddOOiiiOO。如果您的数据结构已修复,则可以执行以下操作:

XX[a-z]{3}OO

选择所有模式,例如XXiiiOO(可以调整以符合您的需求,XX[^X]+?OO例如在XX之前选择最后OO对之间的所有内容最多OO:例如在XXiiiXXdddFFcccOOlll中,它匹配XXdddFFcccOO

答案 2 :(得分:1)

事实上,问题不在于贪婪/非贪婪... @devnull建议的解决方案应该有效,前提是您要避免在XXOO组之间使用单个X.

否则,你将不得不使用一个前瞻(即一块正则表达式“将”前面的“scooting”字符串,并检查它是否可以实现,但实际上没有消耗掉任何字符)。这样的事情:

re.findall(r'XX(?:.(?!XX))*?OO', str)

使用此前瞻性预测,您匹配(非贪婪)任何字符(.,然后XX ...

答案 3 :(得分:1)

行为是由于字符串从左到右处理的事实。避免问题的一种方法是使用否定的字符类:

XX(?:(?=([^XO]+|O(?!O)|X(?!X)))\1)+OO