Чтение символов из файла в Python - PullRequest
91 голосов
/ 29 сентября 2008

В текстовом файле есть строка «Мне это не нравится».

Однако, когда я читаю это в строку, оно становится «я не такой \ xe2 \ x80 \ x98t». Я понимаю, что \ u2018 - это Unicode-представление "'". Я использую

f1 = open (file1, "r")
text = f1.read()

команда для чтения.

Теперь можно ли прочитать строку таким образом, чтобы при ее чтении в строку вместо слов "мне это не нравилось", а не "мне это не нравится" это "?

Второе редактирование: я видел, что некоторые люди используют сопоставление для решения этой проблемы, но на самом деле, нет ли встроенного преобразования, которое делает этот тип преобразования ANSI в Unicode (и наоборот)?

Ответы [ 8 ]

142 голосов
/ 29 сентября 2008

Ссылка: http://docs.python.org/howto/unicode

Поэтому чтение Unicode из файла просто:

import codecs
f = codecs.open('unicode.rst', encoding='utf-8')
for line in f:
    print repr(line)

Также можно открывать файлы в режиме обновления, позволяя читать и писать:

f = codecs.open('test', encoding='utf-8', mode='w+')
f.write(u'\u4500 blah blah blah\n')
f.seek(0)
print repr(f.readline()[:1])
f.close()

РЕДАКТИРОВАТЬ : Я предполагаю, что ваша цель - просто правильно прочитать файл в строку в Python. Если вы пытаетесь преобразовать ASCII-строку из Unicode, то прямого способа сделать это не существует, поскольку символы Unicode не обязательно будут существовать в ASCII.

Если вы пытаетесь преобразовать в строку ASCII, попробуйте одно из следующего:

  1. Замените определенные символы Юникода эквивалентами ASCII, если вы хотите обработать только несколько особых случаев, таких как этот конкретный пример

  2. Используйте normalize() модуля unicodedata и метод string.encode(), чтобы конвертировать как можно лучше в следующий ближайший эквивалент ASCII (Ref https://web.archive.org/web/20090228203858/http://techxplorer.com/2006/07/18/converting-unicode-to-ascii-using-python):

    >>> teststr
    u'I don\xe2\x80\x98t like this'
    >>> unicodedata.normalize('NFKD', teststr).encode('ascii', 'ignore')
    'I donat like this'
    
15 голосов
/ 29 сентября 2008

Есть несколько моментов для рассмотрения.

Символ \ u2018 может появляться только как фрагмент представления строки Unicode в Python, например если ты пишешь:

>>> text = u'‘'
>>> print repr(text)
u'\u2018'

Теперь, если вы просто хотите аккуратно напечатать строку Unicode, просто используйте метод Unicode encode:

>>> text = u'I don\u2018t like this'
>>> print text.encode('utf-8')
I don‘t like this

Чтобы убедиться, что каждая строка любого файла будет читаться как Unicode, вам лучше использовать функцию codecs.open вместо просто open, которая позволяет вам указать кодировку файла:

>>> import codecs
>>> f1 = codecs.open(file1, "r", "utf-8")
>>> text = f1.read()
>>> print type(text)
<type 'unicode'>
>>> print text.encode('utf-8')
I don‘t like this
6 голосов
/ 29 сентября 2008

Но на самом деле это "мне это не нравится", а не "мне это не нравится". Символ u '\ u2018' является совершенно другим символом, чем "" "(и визуально должен больше соответствовать" ").

Если вы пытаетесь преобразовать закодированный юникод в простой ASCII, вы, возможно, можете сохранить отображение знаков препинания Юникода, которое вы хотели бы преобразовать в ASCII.

punctuation = {
  u'\u2018': "'",
  u'\u2019': "'",
}
for src, dest in punctuation.iteritems():
  text = text.replace(src, dest)

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

3 голосов
/ 01 октября 2008

Если оставить в стороне тот факт, что ваш текстовый файл поврежден (U + 2018 - это кавычка слева, а не апостроф): iconv можно использовать для транслитерации символов юникода в ascii.

Вам придется поискать "iconvcodec" в Google, так как модуль, похоже, больше не поддерживается, и я не могу найти каноническую домашнюю страницу для него.

>>> import iconvcodec
>>> from locale import setlocale, LC_ALL
>>> setlocale(LC_ALL, '')
>>> u'\u2018'.encode('ascii//translit')
"'"

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

$ xxd foo
0000000: e280 980a                                ....
$ iconv -t 'ascii//translit' foo | xxd
0000000: 270a                                     '.
2 голосов
/ 29 сентября 2008

Есть вероятность, что у вас есть не-Unicode строка с escape-символами Unicode, например ::100100

>>> print repr(text)
'I don\\u2018t like this'

Это на самом деле случилось со мной однажды. Вы можете использовать кодек unicode_escape для декодирования строки в кодировку Unicode, а затем кодировать ее в любом формате:

>>> uni = text.decode('unicode_escape')
>>> print type(uni)
<type 'unicode'>
>>> print uni.encode('utf-8')
I don‘t like this
1 голос
/ 30 ноября 2018

Также возможно прочитать закодированный текстовый файл, используя метод чтения python 3:

f = open (file.txt, 'r', encoding='utf-8')
text = f.read()
f.close()

В этом варианте нет необходимости импортировать дополнительные библиотеки

1 голос
/ 29 сентября 2008

Это способ Pythons, показывающий строки в кодировке Unicode. Но я думаю, что вы должны быть в состоянии напечатать строку на экране или записать ее в новый файл без каких-либо проблем.

>>> test = u"I don\u2018t like this"
>>> test
u'I don\u2018t like this'
>>> print test
I don‘t like this
1 голос
/ 29 сентября 2008

На самом деле, U + 2018 - это Unicode-представление специального символа ‘. Если вы хотите, вы можете преобразовать экземпляры этого символа в U + 0027 с помощью этого кода:

text = text.replace (u"\u2018", "'")

Кроме того, что вы используете для записи файла? f1.read() должен вернуть строку, которая выглядит следующим образом:

'I don\xe2\x80\x98t like this'

Если он возвращает эту строку, файл записывается неправильно:

'I don\u2018t like this'
...