python正则表达式向前看正面+负面

时间:2015-11-07 07:44:33

标签: python regex regex-lookarounds

这个正则表达式将得到456.我的问题是为什么它不能从1-234-56得到234? 56是否符合(?!\ d))模式,因为它不是一个数字。 (?!\ d))寻找的起点在哪里?

import re
pattern = re.compile(r'\d{1,3}(?=(\d{3})+(?!\d))')
a = pattern.findall("The number is: 123456") ; print(a)

在第一阶段添加逗号分隔符,如123,456。

a = pattern.findall("The number is: 123456") ; print(a)
results = pattern.finditer('123456')
  for result in results:
    print ( result.start(), result.end(), result)

1 个答案:

答案 0 :(得分:1)

  

我的问题是为什么它不能来自234 1-234-56

由于(?=(\d{3})+(?!\d))要求在1-3位序列后出现3位数序列,因此无法实现。 56(您想象的场景中的最后一个数字组)是一个2位数的组。由于量词可以是懒惰的或贪婪的,因此您无法将一个,两个和三个数字组与\d{1,3}匹配。要从234获取123456,您需要专门为其定制的正则表达式:\B\d{3},或(?<=1)\d{3}或甚至\d{3}(?=\d{2}(?!\d))

  

56是否符合(?!\d))模式? (?!\ d))寻找的起点在哪里?

不,这是一个负向前瞻,它不匹配,它只检查输入字符串中当前位置后面是否没有数字。如果有数字,则匹配失败(未找到并返回结果)。

更多关于前瞻的说明:它位于(\d{3})+子模式之后,因此正则表达式引擎开始在最后一个3位数组之后搜索数字,如果找到数字则失败匹配(因为它是一个负面的预测)。简单来说, (?!\d)是此正则表达式中的数字结束/尾随边界

更详细的细分:

  • \d{1,3} - 1到3位数序列,尽可能多(使用贪婪量词)
  • (?=(\d{3})+(?!\d)) - 一个正向前瞻((?=...)),用于检查之前匹配的1-3位数字序列是否后跟
    • (\d{3})+ - 一个或多个(+)正好3位数的序列......
    • (?!\d) - 后面没有数字。

Lookaheads不匹配,不消耗字符,但您仍然可以捕获。执行前瞻时,正则表达式索引与之前的字符相同。 使用正则表达式和输入,您将123\d{1,3}匹配,因为您有3位数序列(456)。但是456在预测中是 capured ,如果设置了捕获组,则re.findall仅返回捕获的文本。

要将逗号添加为数字分组符号,请使用

rx = r'\d(?=(?:\d{3})+(?!\d))'

请参阅IDEONE demo