2014-10-27 21 views
0

我已经看过很多帖子,但我仍然无法使它工作,我不知道为什么。整数模式 - Python的正则表达式

我所拥有的是一个相对简单的字符串,其中包含一些浮点数和整数,例如:'2 1.000000000000000 1 1 0'。我只想从中提取整数,在这个例子中只有2, 1, 1, 0(不是1,后面是0 s)。

我知道我必须使用lookbehindlookahead来排除.之前或之后的数字。我可以成功地找到由昏迷前的数字,在上述情况下,0

import re 
IntegerPattern = re.compile('-?(?<=\.)\d+(?!\.)') 
a = '2 1.000000000000000  1 1 0' 
IntegerPattern.findall(a) 

将返回['000000000000000'],正是我想要的。但是,当我试图找到那些通过.小号前面的数字,这并不工作:

import re 
IntegerPattern = re.compile('-?(?<!\.)\d+(?!\.)') 
a = '2 1.000000000000000  1 1 0' 
IntegerPattern.findall(a) 

回报['2', '00000000000000', '1', '1', '0']。任何想法为什么?一般来说,我对于正则表达式是全新的,这只是让我无法理解。它应该工作,但它不会。任何帮助,将不胜感激。

回答

3

使用正则表达式

(\s|^)\d+(\s|$) 

码即可

>>> n='2 1.000000000000000 1 1 0' 
>>> re.findall(r'(?:\s|^)\d+(?:\s|$)', n) 
['2 ', ' 1 ', ' 0'] 

(\s*|^)相匹配的空间或开始字符串的

\d+匹配任何数量的数字

(\s*|$)比赛空间或结束字符串

注:\b不能用于分隔\d+作为.也被包括在\b

示例http://regex101.com/r/gP1nK0/1

编辑

为什么犯规的正则表达式(?<!\.)\d+(?!\.)工作

现在这里使用的外观负周围的断言,如果问题,我们尽量不匹配.和正则表达式尝试当你写(?<!\.)正则表达式匹配.

发现它可以是全成的位置

即在发言权1.000000正则表达式固定位置第二0使得先前的位置是不.(这是零)和remai宁是00000因而获胜。因此,它与它匹配

得到一个更清晰的视野检查此链接

http://regex101.com/r/gP1nK0/2

正如你所看到的1.000000000000000比赛从第二0使其全成occures

编辑1

更完美的正则表达式会像

(?:(?<=^)|(?<=\s))\d+(?=\s|$)

>>>n 
'1 2 3 4.5' 
>>> re.findall(r'(?:(?<=^)|(?<=\s))\d+(?=\s|$)', n) 
['1', '2', '3'] 
>>> n='1 2 3 4' 
>>> re.findall(r'(?:(?<=^)|(?<=\s))\d+(?=\s|$)', n) 
['1', '2', '3', '4'] 

谢谢SLN指出了这一点

+0

好,谢谢,但这部分是一个学习经验。如果我有一个没有前面空格的字符串,我该怎么办?为什么我的表情不起作用? – 2014-10-27 18:32:59

+0

@AleksanderLidtke,回答你的问题不起作用的原因。如果你计算0的数量,你会注意到它少了一个。从第二个0开始,它不会立即以'\ .'开头,因此它通过。 – smerny 2014-10-27 18:35:42

+0

它工作正常,即使当与空间预告 – nu11p01n73R 2014-10-27 18:36:10

2

我不会用正则表达式打扰:

s = '2 1.000000000000000  1 1 0' 

print [int(part) for part in s.split() if "." not in part] 

人们常常简单得多基本的字符串处理工作,或作为那句老话:“我有一个问题,我试着用正则表达式来解决。然后,我有两个问题”

+0

嗨,同意但我实际上是在学习正则表达式。 – 2014-10-27 18:31:44

1
a = '-2 1.000000000000000  1 1 0' 
print([x for x in a.split() if x[1:].isdigit() or x.isdigit()]) 
['-2', '1', '1', '0'] 

如果您在.也是数字前想:

a = '2 1.000000000000000  1 1 0' 


print([x if x.isdigit() else x.split(".")[0] for x in a.split() ]) 
['2', '1', '1', '1', '0'] 
+0

+1非重新解决方案:P – 2014-10-27 18:17:24

+0

@JoranBeasley,欢呼声,我在想它不适用于负数,但OP似乎没有在它们的正则表达式中检查它,所以我猜它应该工作:P – 2014-10-27 18:19:34

+0

@smerny,它确实得到了第一个 – 2014-10-27 18:29:01

0

该发动机补偿相匹配。
它在左边流下了一个\d,然后匹配。

这将确保没有数字是shed在左侧 -

# (?<![.\d])\d+(?!\.) 

(?<! [.\d]) 
\d+ 
(?! \.) 

只是注意 - 在你的第一个模式-?(?<=\.)\d+(?!\.)
-?将永远不会真正匹配一个破折号,因为它不是一个\.其断言
国家必须在那里。
该规则永远不会指向直接包含文字的方向的断言,除非文字包含在断言中。在这种情况下,无论如何,它是无序的,
所以-?是完全无用的。

+0

当我运行你的模式时:'pat = re.compile('(?<![。\ d])\ d +(?! \。)')'' a ='2 1.000000000000000 1 1 0'我仍然得到'['2','1','000000000000000','1','1']'。并且用' - ?'指出,它只是原始模式的剩余部分。 – 2014-10-27 18:35:39

+0

恐怕这是不可能的!和'pat = re.compile('(?<![。\ d])\ d +(?! \。)')'不是我的模式。 – sln 2014-10-27 18:36:38