Python: разбиение строки по всем пробелам - PullRequest
27 голосов
/ 19 января 2012

Чтобы разбить строки по пробелам в python, обычно используется split метод строки без параметров:

>>> 'a\tb c\nd'.split()
['a', 'b', 'c', 'd']

Но вчера я наткнулся на строку, которая использовала ZERO WIDTH SPACE между словами. Превратив мои новые знания в короткую производительность черная магия (среди пользователей JavaScript), я хотел бы спросить, как лучше разделить все пробельные символы , поскольку split не является достаточно:

>>> u'a\u200bc d'.split()
[u'a\u200bc', u'd']

UPD1

кажется, что решение, предложенное sth, в целом работает, но зависит от некоторых настроек ОС или параметров компиляции Python. Было бы неплохо знать причину (и если настройка может быть включена в Windows).

UPD2 cptphil нашел отличную ссылку , которая все проясняет:

Итак, я связался с Техническим комитетом Unicode по поводу проблемы и сразу получил ответ. Они указали, что ZWSP когда-то считался пробелом, но это было изменено в Unicode 4.0.1

Цитата из сайта Unicode :

Изменение пространства нулевой ширины U + 200B с Zs на Cf (2003.10.27)

Постоянно возникали проблемы с использованием пространства нулевой ширины U + 200B (ZWSP). Функция этого символа состоит в том, чтобы разрешить разрыв строки в местах, где это обычно не допускается, и, таким образом, функционально является символом формата с общей категорией Cf. Это поведение хорошо документировано в Стандарте Юникода, и этот символ не считается пробельным символом в Базе данных символов Юникода. Однако по историческим причинам общая категория по-прежнему Zs (разделитель пробелов), что приводит к неправильному использованию символа. ZWSP также является единственным символом Zs, который не является пробелом. Общая категория может привести к неправильной интерпретации правила D13 Базовый символ, поскольку допускается использование ZWSP в качестве основы для объединения меток.

Предложение состоит в том, чтобы изменить общую категорию U + 200B с Zs на Cf.

Разрешение: Закрыто. Общая категория U + 200B будет изменена с Zs на Cf в Unicode версии 4.0.1.

Затем это изменение было отражено в Python. Результат u'\u200B'.isspace() в Python 2.5.4 и 2.6.5 равен True, в Python 2.7.1 это уже False.

Для других пробелов достаточно обычного split:

>>> u'a\u200Ac'.split()
[u'a', u'c']

А если вам этого недостаточно, добавьте символы один за другим, как подсказывает Gabi Purcaru ниже.

Ответы [ 6 ]

17 голосов
/ 19 января 2012

Редактировать

Оказывается, что \ u200b технически не определяется как пробел, и поэтому python не распознает его как совпадающий \ s даже с включенным флагом Юникода. Поэтому он должен рассматриваться как непробельный символ.

http://en.wikipedia.org/wiki/Whitespace_character#Unicode

http://bugs.python.org/issue13391

import re

re.split(ur"[\u200b\s]+", "some string", flags=re.UNICODE)
6 голосов
/ 19 января 2012

Вы можете использовать регулярное выражение с включенным сопоставлением Юникода:

>>> re.split(r'(?u)\s', u'a\u200bc d')
[u'a', u'c', u'd']
4 голосов
/ 19 января 2012

Вы можете использовать re.split , например:

import re
re.split(u'\s|\u200b', your_string)
2 голосов
/ 19 января 2012

Просто используйте split:

>>> u'\u200b'.isspace()
True
2 голосов
/ 19 января 2012

Можете ли вы использовать что-то вроде этого?

re.split(r'\s+', your_string, re.UNICODE)
2 голосов
/ 19 января 2012

Вы можете использовать модуль 're' и передать разделитель в 'split': http://docs.python.org/library/re.html#re.split

...