токенизировать строку, сохраняя разделители в Python - PullRequest
17 голосов
/ 30 ноября 2009

Есть ли в Python эквивалент str.split, который также возвращает разделители?

Мне нужно сохранить расположение пробелов для вывода после обработки некоторых токенов.

Пример:

>>> s="\tthis is an  example"
>>> print s.split()
['this', 'is', 'an', 'example']

>>> print what_I_want(s)
['\t', 'this', ' ', 'is', ' ', 'an', '  ', 'example']

Спасибо!

Ответы [ 5 ]

19 голосов
/ 30 ноября 2009

Как насчет

import re
splitter = re.compile(r'(\s+|\S+)')
splitter.findall(s)
6 голосов
/ 30 ноября 2009
>>> re.compile(r'(\s+)').split("\tthis is an  example")
['', '\t', 'this', ' ', 'is', ' ', 'an', '  ', 'example']
4 голосов
/ 30 ноября 2009

модуль re обеспечивает эту функциональность:

>>> import re
>>> re.split('(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']

(цитируется в документации по Python).

Для вашего примера (разделить на пробел), используйте re.split('(\s+)', '\tThis is an example').

Ключ заключается в том, чтобы заключить регулярное выражение для разделения в скобках. Таким образом, разделители добавляются в список результатов.

Редактировать: Как указывалось, любые предшествующие / конечные разделители, конечно, также будут добавлены в список. Чтобы избежать этого, вы можете сначала использовать метод .strip() в строке ввода.

0 голосов
/ 30 ноября 2009

Спасибо, ребята, за указание на модуль re, я все еще пытаюсь выбрать между этим и использовать свою собственную функцию, которая возвращает последовательность ...

def split_keep_delimiters(s, delims="\t\n\r "):
    delim_group = s[0] in delims
    start = 0
    for index, char in enumerate(s):
        if delim_group != (char in delims):
            delim_group ^= True
            yield s[start:index]
            start = index
    yield s[start:index+1]

Если бы у меня было время, я бы проверил их xD

...