Чтение символов из файла в Python

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

Однако, когда я читаю его в строке, он становится "I don\xe2\x80\x98t как это". Я понимаю, что \u2018 является уникодным представлением "". Я использую

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

чтобы выполнить чтение.

Теперь, возможно ли прочитать строку таким образом, что когда она считывается в строку, это "мне не нравится это", вместо "I don\xe2\x80\x98t, как это нравится это"?

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

Ответ 1

Ссылка: http://docs.python.org/howto/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()

EDIT. Я предполагаю, что ваша цель - просто прочитать файл в строке в Python. Если вы пытаетесь преобразовать строку ASCII из Unicode, тогда нет прямого способа сделать это, так как символы Unicode не обязательно будут существовать в ASCII.

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

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

  • Используйте unicodedata модуль normalize() и метод 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'
    

Ответ 2

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

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

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

Теперь, если вы просто хотите напечатать строку юникода красиво, просто используйте метод 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

Ответ 3

Но это действительно так: "Я так не люблю", а не "Мне это не нравится". Характер u '\ u2018' является совершенно другим символом, чем "'" (и, визуально, должен соответствовать больше "`).

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

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

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

Ответ 4

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

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

>>> 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                                     '.

Ответ 5

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

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

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

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

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

'I don\u2018t like this'

Ответ 6

Существует вероятность, что у вас есть строка, отличная от юникода, с escape-символами unicode, например:

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

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

>>> uni = text.decode('unicode_escape')
>>> print type(uni)
<type 'unicode'>
>>> print uni.encode('utf-8')
I don‘t like this

Ответ 7

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

>>> test = u"I don\u2018t like this"
>>> test
u'I don\u2018t like this'
>>> print test
I don‘t like this