Python:按分隔符列表拆分字符串

Posted

技术标签:

【中文标题】Python:按分隔符列表拆分字符串【英文标题】:Python: Split string by list of separators 【发布时间】:2011-06-09 11:32:18 【问题描述】:

在 Python 中,我想使用分隔符列表来拆分字符串。分隔符可以是逗号或分号。除非空格位于非空格、非分隔符的中间,否则应删除空格,在这种情况下应保留空格。

测试用例 1:ABC,DEF123,GHI_JKL,MN OP 测试用例2:ABC;DEF123;GHI_JKL;MN OP 测试用例3:ABC ; DEF123,GHI_JKL ; MN OP

听起来像是正则表达式的一个例子,这很好,但如果用另一种方法更容易或更干净,那就更好了。

谢谢!

【问题讨论】:

【参考方案1】:

这应该比正则表达式快得多,您可以根据需要传递分隔符列表:

def split(txt, seps):
    default_sep = seps[0]

    # we skip seps[0] because that's the default separator
    for sep in seps[1:]:
        txt = txt.replace(sep, default_sep)
    return [i.strip() for i in txt.split(default_sep)]

使用方法:

>>> split('ABC ; DEF123,GHI_JKL ; MN OP', (',', ';'))
['ABC', 'DEF123', 'GHI_JKL', 'MN OP']

性能测试:

import timeit
import re


TEST = 'ABC ; DEF123,GHI_JKL ; MN OP'
SEPS = (',', ';')


rsplit = re.compile("|".join(SEPS)).split
print(timeit.timeit(lambda: [s.strip() for s in rsplit(TEST)]))
# 1.6242462980007986

print(timeit.timeit(lambda: split(TEST, SEPS)))
# 1.3588597209964064

还有更长的输入字符串:

TEST = 100 * 'ABC ; DEF123,GHI_JKL ; MN OP , '

print(timeit.timeit(lambda: [s.strip() for s in rsplit(TEST)]))
# 130.67168392999884

print(timeit.timeit(lambda: split(TEST, SEPS)))
# 50.31940778599528

【讨论】:

在我的机器上,我给出的第二种解决方案对于短字符串来说更快。 不要让 default_sep 成为参数,只需使用其中一个 sep。例如:default_sep = seps[0],然后将for 行更改为for sep in seps[1:]: 这依赖于调用者事先知道有一个字符(例如“|”)永远不会出现在输入中。这很容易造成灾难。 这种比较是有缺陷的:它每次都通过循环编译正则表达式。如果您在循环之外正确编译正则表达式 (r = re.compile(",|;")),则正则表达式版本会更快。这也是每个人都能立即理解的清晰、普通、灵活的解决方案,这是比性能更有力的论据。 @blah238, @Joschua: @Glenn Maynard: 在我的机器上: Joschua: 2.30, r=re.compile(...) in setup: 2.18, rs=re.compile(... ).split 设置:2.08。进一步说明:Joschua 的方法是 O(SN),其中 S 是分隔符的数量。【参考方案2】:

使用正则表达式,试试

[s.strip() for s in re.split(",|;", string)]

[t.strip() for s in string.split(",") for t in s.split(";")]

没有。

【讨论】:

宁可通过字符串的split() 来避免导入re,例如'ABC,DEF123,GHI_JKL,MN OP'.split(',|;') @macrog:这不会在",|;"的所有逐字出现处拆分字符串吗? 但是如果你想在 ,; 处分割。您必须为每个字符添加一个 for 循环! @Joshua:但问题表明我们只想拆分,;。无论如何我都会使用正则表达式版本。【参考方案3】:

采取上述答案,在您的测试用例中,您希望使用正则表达式和一个或多个分隔字符。在您的情况下,分隔符似乎是 ',', '|', ';'和空白。 python中的空格是'\w',所以理解是:

import re
list = [s for s in re.split("[,|;\W]+", string)]

我无法回复sven上面的回答,但是我拆分了括号内的一个或多个字符,并且不必使用strip()方法。

哎呀,我没有正确阅读这个问题...... Sven 对脱衣舞的回答有效;我的假设空白是另一种分隔。

【讨论】:

【参考方案4】:
>>> re.split('\s*,\s*|\s*;\s*', 'a , b; cdf')
['a', 'b', 'cdf']

【讨论】:

以上是关于Python:按分隔符列表拆分字符串的主要内容,如果未能解决你的问题,请参考以下文章

python中split的用法分割的字符串怎么命名?

使用oracle按分隔符位置拆分字符串

使用oracle SQL按分隔符位置拆分字符串

4-1如何拆分含有多个分隔符的字符串

按分隔符拆分字符串并跳过分隔符后跟某些字符的部分

使用单词列表作为分隔符的 C++ 拆分字符串