在开始时具有正向lookbehind的正则表达式无法匹配整个字符串

时间:2013-08-05 23:47:20

标签: python regex lookbehind

我在re模块中使用Python并尝试匹配decimal(4,1)decimal(10,5)等字符串,而实际只返回4,110,5,使用以下正则表达式:

(?<=decimal\()\d+,\d+(?=\)$)

假设我使用re.compile编译正则表达式并将其命名为DECIMAL。如果我尝试搜索decimal(4,1)正则表达式的实例,如下所示:

DECIMAL = re.compile(r'(?<=decimal\()\d+,\d+(?=\)$)')
results = DECIMAL.search('decimal(4,1)')

results.group(0)根据需要返回字符串4,1。但是,如果我尝试匹配而不是搜索:

results = DECIMAL.match('decimal(4,1)')

results评估为None

这里match方法是否失败,因为match看起来完全匹配正则表达式的消费部分与干草堆的开头,因此没有任何空间用于前面的正长度模式确认?

至于实际情况,在这种情况下,简单搜索不起作用,因为DECIMAL会导致产生不可接受的字符串,如snarfdecimal(4,1)。我应该在某处开始使用字符串开头的标记,还是还有其他我完全遗漏的东西?

2 个答案:

答案 0 :(得分:2)

search()不同,Python的match()方法会自动将匹配锚定在字符串的开头。这意味着您在字符串的开头之前尝试匹配文字字符串decimal( ,这当然总是会失败。

as Jared pointed out,无论如何你都不需要为了这个。事实上,lookbehind应该是你达到的 last 工具,而不是第一个。

这是Jared正则表达式的略微修改版本:

r'\bdecimal\(\s*(\d+\s*,\s*\d+)\s*\)'

最重要的变化是添加了单词边界(\b)以防止它与snarfdecimal(4,1)之类的内容匹配。如果您真的必须使用match()而不是search(),则可以使用.*?“填充”正则表达式,强制它使用中间字符:

r'.*?\bdecimal\(\s*(\d+\s*,\s*\d+)\s*\)'

答案 1 :(得分:1)

你根本不需要使用正面的后视镜,

>>> import re
>>> find_decimal = re.compile(r'decimal\((\d+,\d+)\)')
>>> find_decimal.match('decimal(4,1)').group(1)
'4,1'

至于它不起作用的原因,不确定,但我猜你的想法是正确的。