re.split()后的尾随空字符串

2024-10-01 13:35:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个字符串,我想把数字序列和其他的东西分开

例如:

import re
s = 'abc123abc'
print(re.split('(\d+)', s))
s = 'abc123abc123'
print(re.split('(\d+)', s))

输出如下所示:

['abc','123','abc']
['abc','123','abc','123','

注意,在第二种情况下,后面有一个空字符串

显然,我可以测试它,并在必要时删除它,但它似乎很麻烦,我想知道RE是否可以改进以适应这种情况


Tags: 字符串importre情况序列数字splitabc
3条回答

为此使用正则表达式的简单方法是^{}

def bits(s):
    return re.findall(r"(\D+|\d+)", s)

bits("abc123abc123")
# ['abc', '123', 'abc', '123']

但是使用^{}似乎更容易、更自然。毕竟,您正在基于单个条件对iterable进行分块:

from itertools import groupby

def bits(s):
    return ["".join(g) for _, g in groupby(s, key=str.isdigit)]

bits("abc123abc123")
# ['abc', '123', 'abc', '123']

您可以使用filter并且不要像下面那样返回此空字符串:

>>> s = 'abc123abc123'
>>> re.split('(\d+)', s)
['abc', '123', 'abc', '123', '']

>>> list(filter(None,re.split('(\d+)', s)))
['abc', '123', 'abc', '123']

通过感谢@chepner,您可以生成如下列表:

>>> [x for x in re.split('(\d+)', s) if x]
['abc', '123', 'abc', '123']

如果您可能有符号或其他,则需要split

>>> s = '&^%123abc123$#@123'
>>> list(filter(None,re.split('(\d+)', s)))
['&^%', '123', 'abc', '123', '$#@', '123']

这与re.split()本身的实现有关:您不能更改它。当函数拆分时,它不会检查捕获组后面的任何内容,因此它不能为您选择保留或丢弃拆分后留下的空字符串。它只是在那里拆分,并将字符串的其余部分(可以为空)留到下一个周期

如果您不想要那个空字符串,可以在将结果收集到列表中之前以各种方式除去它。user1740577就是一个例子,但就我个人而言,我更喜欢列表理解,因为它更适合于简单的过滤器/映射操作:

parts = [part for part in re.split('(\d+)', s) if part]

我建议不要在列表已经创建之后检查并删除元素,因为它涉及更多的操作和分配

相关问题 更多 >