2009-11-30 4 views
17

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

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

Пример:

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

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

Спасибо!

+1

+1 - Интересный вопрос, 'splitlines', кажется, есть' keepends' параметр, но нет такой вещи для 'split'. Кажется странным (http://docs.python.org/library/stdtypes.html#str.splitlines). –

ответ

19

Как насчет

import re 
splitter = re.compile(r'(\s+|\S+)') 
splitter.findall(s) 
+0

элегантный и легко расширяемый (думаю, '(\ s + | \ w + | \ S +)'). – hop

6
>>> re.compile(r'(\s+)').split("\tthis is an example") 
['', '\t', 'this', ' ', 'is', ' ', 'an', ' ', 'example'] 
4

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

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

(цитата из документации Python).

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

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

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

+0

, не использующий строку OP, маскирует тот факт, что пустая строка включена в качестве первого элемента возвращаемого списка. – hop

+0

Спасибо. Я отредактировал свой пост соответственно (хотя в этом случае спецификация OP («хотите сохранить пробел») и его пример были противоречивыми). –

+0

Нет, это не было ... был один пример текущего поведения и еще один из желаемого. – fortran

-1

Спасибо ребята за указание на 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

+0

нет необходимости в регулярном выражении или создании собственных колес, если у вас есть python 2.5 и далее. См. Мой ответ. – ghostdog74

3

Вы посмотрели на pyparsing? Пример заимствован из the pyparsing wiki:

>>> from pyparsing import Word, alphas 
>>> greet = Word(alphas) + "," + Word(alphas) + "!" 
>>> hello1 = 'Hello, World!' 
>>> hello2 = 'Greetings, Earthlings!' 
>>> for hello in hello1, hello2: 
...  print (u'%s \u2192 %r' % (hello, greet.parseString(hello))).encode('utf-8') 
... 
Hello, World! → (['Hello', ',', 'World', '!'], {}) 
Greetings, Earthlings! → (['Greetings', ',', 'Earthlings', '!'], {})