Python正则表达式:使用交替强制贪婪匹配

时间:2015-01-26 05:44:11

标签: python regex

我有一个形式的正则表达式:

a(bc|de|def)g?

在字符串adefg上,此模式仅匹配" ade"这显然是在交替组的第一场比赛中退出。从" g"中移除?选项token允许模式匹配整个字符串。这是有道理的,因为"?"不贪心。 [编辑:我已经纠正了,"?" 贪婪,这似乎增加了我的困惑。在我看来,如果"?"非贪婪,这使得模式可以在有更大的匹配时提前退出。]

我想避免在交替中重新排列字符串的顺序,我可以通过将(\ b | $)附加到模式来解决问题,但现在我真的很想知道是否还有其他溶液

例如,有没有办法制作"?"贪婪或强迫轮换不要在第一场比赛中退出?

2 个答案:

答案 0 :(得分:3)

您无法使|从左到右与其成分不匹配,因为从左到右匹配是其documented行为。即使你可以使?"贪婪",它也不会起作用,因为正则表达式从头到尾匹配,所以?的贪婪无法实现。 ; t在交替已经匹配之前有效。

贪婪并没有使正则表达式引擎回过头来找到更好的方法"匹配;它将与第一种方式相匹配。它只会使用g?,如果它必须这样做才能使整个比赛成功,并且如果它可以忽略它并且坚持它在交替。换句话说,一旦它匹配" ade",它就可以成功并停止(因为它不需要 来匹配" g",因为它是可选的)。因此它甚至不考虑交替的其他部分,因为它可以找到一种方法使其使用第一个工作。一个贪婪的?没有让它返回并重试已经匹配的其他事情,除非它需要整个比赛成功。

如果你正在使用一些交替,其中一些交替是其他的子串,你应该把它们整理好,以便最长的交替出现。

另一种可能性是在正则表达式的末尾添加$。这将强制它一直到字符串的末尾,所以它回溯并尝试其他替代方案,因为现在" ade"不会匹配(因为它与$不匹配)。但是,这只有在您确实想要匹配整个字符串时才有效。

答案 1 :(得分:-1)

重构这个表达式的一个显而易见的方法是"展开"可选部分:

a(bc|de|def)g|a(bc|de|def)

(a(bc|de|def))g|\1

避免重复。