Python: разделить строку по списку разделителей

в Python, я хотел бы разделить строку, используя список разделителей. Разделители могут быть запятыми или точками с запятой. Пробел должен быть удален, если он не находится в середине не-пробелов, символов без разделителя, и в этом случае он должен быть сохранен.

тестовый пример 1:ABC,DEF123,GHI_JKL,MN OP
Тестовый случай 2: ABC;DEF123;GHI_JKL;MN OP
Тестовый пример 3: ABC ; DEF123,GHI_JKL ; MN OP

звучит как случай для регулярных выражений, что нормально, но если проще или чище сделать это по-другому это было бы еще лучше.

спасибо!

4 ответов


Это должно быть намного быстрее, чем регулярное выражение, и вы можете передать список разделителей, как вы хотели:

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

    # we skip seps[0] because that's the default seperator
    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.6733491150007467

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

используя регулярные выражения, попробуйте

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

или

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

без.


>>> re.split('\s*,\s*|\s*;\s*', 'a , b; cdf')
['a', 'b', 'cdf']

принимая вышеуказанный ответ, с вашими тестовыми случаями вы хотите использовать регулярное выражение и один или несколько разделение персонажей. В вашем случае символы разделения кажутся ',', '|', ';' и Пробел. Пробел в python - "\w", поэтому понимание:

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

Я не могу ответить на ответ Свена выше, но я разделяю один или несколько символов внутри скобок и не должен использовать метод strip ().

Yikes, я не читал Вопрос Правильный... Ответ Свена с полосой работает; мой предполагает, что пробелы - это еще одно разделение.