Python中的可变宽度Lookbehind问题

时间:2014-07-28 01:34:47

标签: python regex lookbehind negative-lookahead

我有以下情况:

1) car on the right shoulder
2) car on the left shoulder
3) car on the shoulder

我想匹配"肩膀"当左边没有时。所以只有3)回归"肩膀"

re.compile(r'(?<!right|right\s*)shoulder')
sre_constants.error: look-behind requires fixed-width pattern

好像我不能使用\ s *和&#34; |&#34;

我该如何解决这个问题。

提前致谢!

3 个答案:

答案 0 :(得分:17)

regex module:可变宽度lookbehind

除了answer by HamZa之外,对于Python中任何复杂性的任何正则表达式,我建议使用未完成的regex module by Matthew Barnett。它支持无限的looknehind - 这是为数不多的几个引擎之一,以及.NET和JGSoft。

这允许你这样做:

import regex
if regex.search("(?<!right |left )shoulder", "left shoulder"):
    print("It matches!")
else:
    print("Nah... No match.")

如果您愿意,也可以使用\s+

<强>输出:

It matches!

答案 1 :(得分:2)

在大多数正则表达式引擎中,lookbehinds需要具有固定宽度。这意味着您不能在Python +*?中使用量词视图。解决方案是将\s*移到您的外观背后:

(?<!left|right)\s*shoulder

您会注意到此表达式与每个组合相匹配。因此,我们需要将量词从*更改为+

(?<!left|right)\s+shoulder

此解决方案的唯一问题是,如果它位于字符串的开头,它将找不到shoulder,因此我们可能会添加一个带锚的替代方案:

^shoulder|(?<!left|right)\s+shoulder

如果你想摆脱空格,只需使用条形函数。

Online demo

答案 2 :(得分:0)

通过将定宽正向后向与负向前向相结合,可以避免对可变宽度后向的需求:

re.split('(?<=[\u4e00-\u9fff])(?![\u4e00-\u9fff])', '缩头乌龟suō tóu wūguī', 1)
# >>> Out[47]: ['缩头乌龟', 'suō tóu wūguī']