2

字符串:XXaaaXXbbbXXcccXXdddOO

我想匹配以 'XX' 开头以 'OO' 结尾的最小字符串。

所以我写了非贪婪的注册:r'XX.*?OO'

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

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

然后我知道我一定是弄错了,因为上面的限定符将首先匹配“XX”,然后显示它是“非贪婪的”。

但我仍然想弄清楚我怎样才能直接得到我的结果['XXdddOO']。任何回复表示赞赏。

到现在为止,重点其实不是非贪心,或者说,是我眼中的非贪心:左限定符(XX)和右限定符( OO). 当然事实是字符串是从左到右处理的。

4

4 回答 4

5

怎么样:

.*(XX.*?OO)

比赛将在第 1 组进行。

于 2014-01-25T11:34:20.770 回答
2

事实上,问题不在于贪婪/非贪婪......@devnull 建议的解决方案应该有效,前提是您希望避免在您的XXOO组之间出现一个 X。

否则,您将不得不使用前瞻(即一段正则表达式,它将“向前移动”字符串,并检查它是否可以实现,但实际上不消耗任何字符)。像这样的东西:

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

通过这种否定的前瞻,您可以(非贪婪地)匹配任何跟在后面的字符 ( .) ...</p> XX

于 2014-01-25T12:09:57.277 回答
2

正则表达式从左到右工作:非贪婪意味着它将匹配XXaaaXXdddOO而不是XXaaaXXdddOOiiiOO。如果您的数据结构是固定的,您可以这样做:

XX[a-z]{3}OO

选择所有模式,例如XXiiiOO(可以根据您的需要进行调整,XX[^X]+?OO例如选择最后XX一对OO之间的所有内容OO:例如,XXiiiXXdddFFcccOOlll它会匹配XXdddFFcccOO

于 2014-01-25T11:24:07.787 回答
1

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

XX(?:(?=([^XO]+|O(?!O)|X(?!X)))\1)+OO
于 2014-01-25T13:09:31.017 回答