2009-03-15 6 views
11

Как правильно разбить строку, содержащую предложение со специальными символами, используя пробелы в качестве разделителя? Используя метод разделения регулярных выражений, я не могу получить желаемый результат.python, regex split и специальный символ

Пример кода:

# -*- coding: utf-8 -*- 
import re 


s="La felicità è tutto" # "The happiness is everything" in italian 
l=re.compile("(\W)").split(s) 

print " s> "+s 
print " wordlist> "+str(l) 
for i in l: 
    print " word> "+i 

Выход:

s> La felicità è tutto 
wordlist> ['La', ' ', 'felicit', '\xc3', '', '\xa0', '', ' ', '', '\xc3', '', '\xa8', '', ' ', 'tutto'] 
word> La 
word> 
word> felicit 
word> Ã 
word> 
word> ? 
word> 
word> 
word> 
word> Ã 
word> 
word> ? 
word> 
word> 
word> tutto 

в то время как я искал выход как:

s> La felicità è tutto 
wordlist> ['La', ' ', 'felicità', ' ', 'è', ' ', 'tutto'] 
word> La 
word> 
word> felicità 
word> 
word> è 
word> 
word> tutto 

Следует отметить, что ев является строкой который возвращается из другого метода, поэтому я не могу заставить кодировку как

s=u"La felicità è tutto" 

В официальной документации на юникод и рег-код на русском языке я не нашел удовлетворительного объяснения.

Спасибо.

Алессандро

+1

Вы разделяете символы, отличные от слов, которые включают не только пробелы, но (по-видимому) и акцентированные символы. – mpen

ответ

16

Ваше регулярное выражение должно быть (\s) вместо (\W) так:

l = re.compile("(\s)").split(s) 

Код выше даст вам точный вывод, который вы просили. Однако следующая строка имеет смысл:

l = re.compile("\s").split(s) 

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

+0

Спасибо, он работает над печатью отдельных слов. Почему печать списка содержит шестнадцатеричный код Unicode вместо декодированных символов? – alexroat

+0

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

+0

Спасибо, Андрей. Вы полностью ответили на все мои сомнения. – alexroat

4

Попробуйте определение кодировки для регулярного выражения:

l=re.compile("\W", re.UNICODE).split(s) 
+0

Это не работает, я уже пробовал это ... Однако решение Andrew Hare работает хорошо. – alexroat

+0

Вы пробовали без круглых скобок? – kgiannakakis

+0

Да, но поведение похоже на разделение строк (оно удаляет пробелы), и я хочу их поддерживать. Однако re.UNICODE испортил кодировку, изменив некоторые символы. – alexroat

3

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

s = 'La felicità è tutto' 
words = s.split() 
+0

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

+0

@alexroat: Почему именно вам нужны пробелы? Вы знаете, что происходит между каждым словом (элементом списка), не может ли ваш алгоритм добавить их туда, где это необходимо? – mpen

0

Ну, после некоторых дальнейших тестов Эндрю Hare ответ я видел этот символ, как () [] - и т. д. больше не рассматриваются как разделители, в то время как я хочу разбить предложение (поддерживая весь разделитель) словами, составленными с ансамблем буквенно-цифровых значений, которые в конечном итоге расширены с помощью акцентированных символов (то есть все, помеченное как буквенно-цифровое в unicode). Итак, решение kgiannakakis является более правильным, но оно пропускает преобразование строки s в формат unicode.

Возьмите это продолжение первого примера:

# -*- coding: utf-8 -*- 
import re 
s="(La felicità è tutto)"#no explicit unicode given string (UTF8) 
l=re.compile("([\W])",re.UNICODE).split(unicode(s,'utf-8'))#split on s converted to unicode from utf8 

print " string> "+s 
print " wordlist> "+str(l) 
for i in l: 
    print " word> "+i 

Выход сейчас:

string> (La felicità è tutto) 
wordlist> [u'', u'(', u'La', u' ', u'felicit\xe0', u' ', u'\xe8', u' ', u'tutto', u')', u''] 
word> 
word> (
word> La 
word> 
word> felicità 
word> 
word> è 
word> 
word> tutto 
word>) 
word> 

Это именно то, что я ищу.

Приветствия :)

Алессандро

3

с использованием Юникода регулярное выражение будет работать, если вы дать ему юникод строку, чтобы начать с (что вы не в указанном примере). Попробуйте это:

s=u"La felicità è tutto" # "The happiness is everything" in italian 
l=re.compile("(\W)",re.UNICODE).split(s) 

print " s> "+s 
print " wordlist> "+str(l) 
for i in l: 
    print " word> "+i 

Результаты:

s> La felicità è tutto 
wordlist> [u'La', u' ', u'felicit\xe0', u' ', u'\xe8', u' ', u'tutto'] 
word> La 
word> 
word> felicità 
word> 
word> è 
word> 
word> tutto 

Ваша строка s создается как str типа, и, вероятно, будет в UTF-8 кодировке, которая отличается от Юникода.

Смежные вопросы