拆分返回不匹配项

时间:2019-05-08 14:55:59

标签: python regex

在模式中将split与一个捕获组结合使用时,Python返回意外的,不匹配的值。

例如,下面的代码应该返回“ a”或数字。确实,当将它与findall一起使用时,split会返回不匹配项和空字符串。

x = re.compile(r'(a|-?[0-9]+)')

# returns ['45', '444', '19', 'a']
print(x.findall("45, 444 < 19, abc"))

# returns ['', '45', ', ', '444', ' < ', '19', ', ', 'a', 'bc']
print(x.split("45, 444 < 19, abc"))

findall会达到预期的结果。我不明白为什么split的行为会有所不同。

编辑:同样,当您不使用捕获组时,findall仍然可以工作,但由于不返回匹配的结果,分割也会变得更糟。

3 个答案:

答案 0 :(得分:2)

您可以在re.split中略微更改正则表达式:

import re
print(list(filter(None, re.split('[^\da]+', "45, 444 < 19, abc"))))

输出:

['45', '444', '19', 'a']

答案 1 :(得分:1)

what split is supposed to do似乎有误解,它与findall有何不同。基本上,没有捕获组,split应该准确返回findall不返回的部分。毕竟,它将split匹配的字符串str.split>>> re.findall(r'(a|-?[0-9]+)', "45, 444 < 19, abc") ['45', '444', '19', 'a'] >>> re.split(r'a|-?[0-9]+', "45, 444 < 19, abc") ['', ', ', ' < ', ', ', 'bc'] 一样,但是使用正则表达式模式。

findall

with 一个捕获组,如您的情况,将同时返回匹配项(如split)和两者之间的内容(如>>> sorted(_ + __) == sorted(re.split(r'(a|-?[0-9]+)', "45, 444 < 19, abc")) True )。

split

findallsplit 可以互换使用,例如如果您想查找与某种模式匹配的所有内容,但是该模式非常复杂,则可能更容易找到该模式的 complement 的正则表达式,而改用findall,或者反之亦然。但是通常,如果您想查找内容,则应使用{{1}}。

答案 2 :(得分:1)

re.split的文档指出,如果您使用捕获组,则也会返回这些文档。因此,您拆分了表达式并返回捕获组。

您的模式(a|-?[0-9]+)在一个组中捕获:

45
444
19
a

不匹配的是(并因此返回)

, 
 < 
 , 

结果:

['', '45', ', ', '444', ' < ', '19', ', ', 'a', 'bc']

由于在[0-9]+上进行了拆分,因此第一个条目为空,因为它是从字符串的开头进行拆分的。