使用lookhead / lookaround查找句子中的所有数字

时间:2014-12-17 21:47:43

标签: python regex

这是句子('Line#:'不是句子的一部分):

Line1: Number 1 is 100, number 2 is 4.567
Line2: Number 11 is 101, number 21 is 44.567
Line3: Number 111 is 102, number 211 is 444.567

我想在python中构造一个正则表达式,以返回每一行的所有数字:

Line 1 returns: [1, 100, 2, 4.567]
Line 2 returns: [11, 101, 21, 44.567]
Line 3 returns: [111, 102, 211, 444.567]

我提出的正则表达式:

(?<=Number )\d*

仅返回:[1],[11],[111]

以下内容不会返回任何内容:

(?<=Number )\d*(?<= is )\d*(?<=, number )\d*(?<= is )\d*

请帮忙。

2 个答案:

答案 0 :(得分:3)

>>> s="Number 1 is 100, number 2 is 4.567"
>>> import re
>>> re.findall(r'\b[\d\.]+\b',s)
['1', '100', '2', '4.567']

并转换为intfloat

>>> try :
...  map(int,re.findall(r'[\d\.]+',s))
... except:
...  map(float,re.findall(r'[\d\.]+',s))
... 
[1.0, 100.0, 2.0, 4.567]

答案 1 :(得分:1)

您的lookbehind (?<=Number )\d*适用于第一个数字,但由于默认情况下正则表达式匹配区分大小写,因此单词"number"后面的数字不匹配。要更改此行为,您可以添加re.I标志以忽略大小写:

>>> s = "Number 1 is 100, number 2 is 4.567"
>>> re.findall(r"(?<=Number )\d+", s, re.I)
['1', '2']

如果你想对整个任务使用lookbehind断言,你可以这样做:

>>> re.findall(r"(?<=Number )\d+|(?<=Is )[\d\.]+", s, re.I)
['1', '100', '2', '4.567']

管道|的意思是“或”,因此我们匹配前面带有"Number "的数字,前面带有"Is "的数字(忽略信件的情况)。

重要的一点是,lookbehind需要一个固定宽度的断言:我们不能用(?<=Number |Is )之类的东西将表达式“简化”为一个lookbehind断言,因为这两个词的长度不同。由于同样的原因,涉及+*等语法的表达式不能用于lookbehinds。