我有一个形式的正则表达式:
a(bc|de|def)g?
在字符串adefg
上,此模式仅匹配" ade"这显然是在交替组的第一场比赛中退出。从" g"中移除?
选项token允许模式匹配整个字符串。这是有道理的,因为"?"不贪心。 [编辑:我已经纠正了,"?" 贪婪,这似乎增加了我的困惑。在我看来,如果"?"非贪婪,这使得模式可以在有更大的匹配时提前退出。]
我想避免在交替中重新排列字符串的顺序,我可以通过将(\ b | $)附加到模式来解决问题,但现在我真的很想知道是否还有其他溶液
例如,有没有办法制作"?"贪婪或强迫轮换不要在第一场比赛中退出?
答案 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
避免重复。