Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Общие вопросы > модуль re не дружит с буквой ч?


Автор: kulibinka 20.11.2006, 15:12
Цель - получить все английские и русские слова из текста (т.е. как минимум убрать разные знаки препинания). 

Есть ф-я: 

Код

def only_words (text):
  tokens = re.compile(r"[\w']+", re.UNICODE)
  words = tokens.findall(text)
  return "\n".join(words) 


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

text = "чукча чукчу. Чичибечит? - давай-давай one two 12" 

Результат работы only_words (text) следующий: 

ук
а
ук
у
и
ибе
ит
давай
давай
one
two
12 

В чем может быть проблема с этой буквой?

Автор: J2A 20.11.2006, 17:17
А так?
Код

import re
tokens = re.compile("[\w']+", re.UNICODE)
def only_words(text):
    assert isinstance(text, unicode), "Text must be unicode"
    global tokens
    words = tokens.findall(text)
    return '\n'.join(words)

Автор: kulibinka 20.11.2006, 17:46
О, уже близко.

Так получаю ошибку

Код

  File "D:\__my_code\_shingles\shingles.py", line 154, in only_words
    assert isinstance(text, unicode), "Text must be unicode"
AssertionError: Text must be unicode



Когда делаю так:

Код

import re
tokens = re.compile("[\w']+", re.UNICODE)
def only_words(text):
    text = unicode(text, 'cp1251')
    assert isinstance(text, unicode), "Text must be unicode"
    global tokens
    words = tokens.findall(text)
    return '\n'.join(words)


То уже буква Ч появляется, но потом вся работа скрипта рушится (эта ф-я возвращает результат не в той кодировке, на которую расчитана остальная часть)

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

Добавлено @ 17:55 
сделал так:

Код
...
decoded = []
for word in words:
   decoded.append(word.encode('cp1251'))
return decoded


Заработало как надо smile
Огромное спасибо J2A за помощь.

Автор: J2A 20.11.2006, 19:20
Угу, в верном направлении. Просто re.UNICODE означает, что обрабатываемый текст должен быть в уникоде. Если во всей остальной программе текст 8-битный, то нужно перекодировать. Однако все же лучше внутри программы использовать уникод, а перекодировки делать только на входе/выходе. Ну и маленький tip:
Код

return [w.decode('cp1251') for w in words]

и выглядит более компактно, и работает быстрей.

Автор: albertn 21.11.2006, 09:58
Цитата(J2A @  20.11.2006,  19:20 Найти цитируемый пост)
Однако все же лучше внутри программы использовать уникод, а перекодировки делать только на входе/выходе
А еще лучше, если перекодить при вводе/выводе, а всю программу строить на юникоде. Во первых идеологически правильно, во вторых никаких проблем с различными функциями.

Автор: J2A 21.11.2006, 13:34
То же самое сказал.

Автор: kulibinka 21.11.2006, 15:59
Еще раз спасибо всем за полезные советы - глядишь, так я и научу свой питон с кирилицей дружить smile

Автор: albertn 22.11.2006, 09:37
Цитата(J2A @  21.11.2006,  13:34 Найти цитируемый пост)
То же самое сказал. 
А вот и не тоже. Ты предложил  на входе/выходе из подпрограммы, а я предложил при считывании/записи и во всей программе использовать юникод.

Автор: J2A 22.11.2006, 11:50
Вот упертый. Читай внимательней. Покажи слово "подпрограмма" и поясни не являются ли "вход/выход" и "ввода/вывод" синонимами?

Автор: albertn 22.11.2006, 13:18
Цитата(J2A @  22.11.2006,  11:50 Найти цитируемый пост)
Вот упертый. Читай внимательней. Покажи слово "подпрограмма" и поясни не являются ли "вход/выход" и "ввода/вывод" синонимами?
Эти слова совершенно не являются синонимами.
Что есть вход/выход? Когда что-то куда-то входит или откуда-то выходит. Я понимаю это понятие именно так:
Есть определенный независимый участок кода (подпрограмма). При запуске этой подпрограммы передаются определенные параметры (входные данные). Подпрограмма их обрабатывает, и возвращает результат (выходные данные).
И на мой взгляд фраза перекодировки делать только на входе/выходе означает то-же самое что и перекодировать только входные/выходные данные]. А входные/выходные данные относятся как раз к выполнению подпрограмм.
Я же говорю про ввод/вывод, а именно ввод с клавиатуры, чтение файла, получение информации со стороннего источника, вывод на экран, запись в файл, передача параметров сторонним программам, и т.д. А во всей программе операции должны производиться с юникодом

Автор: J2A 22.11.2006, 16:17
Пусть так. Хорошь толочь воду в ступе.

Автор: albertn 23.11.2006, 09:22
Цитата(J2A @  22.11.2006,  16:17 Найти цитируемый пост)
Пусть так. Хорошь толочь воду в ступе. 
Да ичего личного, просто я 
Цитата(J2A @  22.11.2006,  11:50 Найти цитируемый пост)
упертый
и с этим уже ничего не поделаешь smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)