Обрабатывать строку без ascii кода в python

Это действительно запутанно обрабатывать не-ascii-код char в python. Может ли кто-нибудь объяснить?

Я пытаюсь прочитать простой текстовый файл и заменить все неалфавитные символы пробелами.

У меня есть список символов:

ignorelist = ('!', '-', '_', '(', ')', ',', '.', ':', ';', '"', '\'', '?', '#', '@', '$', '^', '&', '*', '+', '=', '{', '}', '[', ']', '\\', '|', '<', '>', '/', u'—')

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

    for punc in ignorelist:
        token = token.replace(punc, ' ')

обратите внимание на символ символа non ascii в конце ignorelist: u'—'

Каждый раз, когда мой код встречает этот символ, он падает и говорит:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position

Я попытался объявить кодировку, добавив # -*- coding: utf-8 -*- в начало файла, но все же не работая. кто знает почему? Спасибо!

Ответ 1

Вы используете Python 2.x, и он попытается автоматически преобразовать unicode и plain str s, но часто не получается с символами, отличными от ascii.

Нельзя смешивать unicode и str вместе. Вы можете либо придерживаться unicode s:

ignorelist = (u'!', u'-', u'_', u'(', u')', u',', u'.', u':', u';', u'"', u'\'', u'?', u'#', u'@', u'$', u'^', u'&', u'*', u'+', u'=', u'{', u'}', u'[', u']', u'\\', u'|', u'<', u'>', u'/', u'—')

if not isinstance(token, unicode):
    token = token.decode('utf-8') # assumes you are using UTF-8
for punc in ignorelist:
    token = token.replace(punc, u' ')

или используйте только обычный str (обратите внимание на последний):

ignorelist = ('!', '-', '_', '(', ')', ',', '.', ':', ';', '"', '\'', '?', '#', '@', '$', '^', '&', '*', '+', '=', '{', '}', '[', ']', '\\', '|', '<', '>', '/', u'—'.encode('utf-8'))
# and other parts do not need to change

Путем ручной кодировки вашего u'—' в str, Python не будет пытаться это сделать сам по себе.

Я предлагаю вам использовать unicode всю свою программу, чтобы избежать подобных ошибок. Но если это будет слишком много, вы можете использовать последний метод. Однако будьте осторожны, когда вы вызываете некоторые функции в стандартной библиотеке или сторонних модулях.

# -*- coding: utf-8 -*- сообщает Python, что ваш код написан в UTF-8 (или вы получите SyntaxError).

Ответ 2

Ввод вашего файла не является utf-8. Поэтому, когда вы нажимаете на этот символ юникода, ваш входной бафф по сравнению, потому что он рассматривает ваш вход как ascii.

Попробуйте вместо этого прочитать файл.

import codecs
f = codecs.open("test", "r", "utf-8")