Преобразовать строку Unicode в строку в Python (содержащую дополнительные символы)


504

Как преобразовать строку Unicode (содержащую дополнительные символы, такие как £ $ и т. Д.) В строку Python?


2
Нам нужно знать, какую версию Python вы используете, и что вы называете строкой Unicode. Выполните следующие действия с короткой строкой unicode_string, которая включает символы валюты, которые вызывают беспокойство: Python 2.x: print type(unicode_string), repr(unicode_string)Python 3.x: print type(unicode_string), ascii(unicode_string)Затем отредактируйте свой вопрос и скопируйте / вставьте результаты вышеприведенного оператора печати. НЕ перепечатывать результаты. Также посмотрите вверху вашего HTML-кода и посмотрите, можете ли вы найти что-то вроде этого: <meta http-equ = "Content-Type" content = "text / html; charset = iso-8859
— Джон Мачин

3
Я сомневаюсь, что вы получите Unicode из веб-запроса. Вы, вероятно, получите кодировку UTF-8 Unicode.

28
@lutz: как именно "кодировка UTF-8 Unicode" не является Unicode?
— Джалф

2
Вы действительно должны уточнить , что вы подразумеваете под юникод строки и питона строки (давая конкретные примеры было бы лучше , я думаю) , как это видно из комментариев существуют различные интерпретации вашего вопроса. Интересно, почему вы этого не сделали, хотя прошло более 3,5 лет с тех пор, как вы задали этот вопрос.
— Петр Доброгост

6
@jalf: если он закодирован ; это больше не Unicode, например,unicode_string = u"I'm unicode string"; bytestring = unicode_string.encode('utf-8'); unicode_again = bytestring.decode('utf-8')
— JFS

Ответы:


573

Видеть unicodedata.normalize

title = u"Klüft skräms inför på fédéral électoral große"
import unicodedata
unicodedata.normalize('NFKD', title).encode('ascii', 'ignore')
'Kluft skrams infor pa federal electoral groe'

24
+1 отвечает на вопрос как сформулированный, проблема @ williamtroup в невозможности сохранить юникод в файл звучит как совершенно другая проблема, достойная отдельного вопроса
— Марк Родди

5
@ Джон - этот ответ предшествует разъяснению ОП.
— Доминик Роджер

10
@Mark Roddy: Его вопрос в том виде, в котором он написан, заключается в том, как преобразовать «строку Unicode» (что бы он ни имел в виду), содержащий некоторые символы валюты, в «строку Python» (что угодно ...), и вы думаете, что remove-some-diacritics delete-other-non-ascii символы Kludge отвечает на его вопрос ???
— Джон Мачин

13
@JohnMachin Это отвечает на вопрос слово в слово: единственный способ преобразовать unicodeстроку в a str- это удалить или преобразовать символы, которые не могут быть представлены в ASCII. Так что +1 от меня.
— Иската,

4
@lzkata: нет, это не так. type(title) == unicode and type(title.encode('utf-8')) == str, Нет необходимости повреждать ввод, чтобы получить строку байтов, которую можно сохранить в файл.
— JFS

319

Вы можете использовать кодирование в ASCII, если вам не нужно переводить не-ASCII символы:

>>> a=u"aaaàçççñññ"
>>> type(a)
<type 'unicode'>
>>> a.encode('ascii','ignore')
'aaa'
>>> a.encode('ascii','replace')
'aaa???????'
>>>

4
Потрясающий ответ. Именно то, что мне было нужно. Кроме того, отличная презентация, чтобы показать эффект ignoreпротивreplace
— Джонни Брукс

или a.encode('ascii', 'xmlcharrefreplace')дает 'aaa&#224;&#231;&#231;&#231;&#241;&#241;&#241;'.
— Боб Стейн

type(a)находится strв Python 3.6.8 и не имеет никакого encode()метода.
— Али То

138
>>> text=u'abcd'
>>> str(text)
'abcd'

Если строка содержит только символы ascii.


18
Это будет работать только на окнах. И сломается, если есть не-ASCII символы.
— Вануан

6
Это прерывается, если содержимое строки действительно Unicode, а не только символы ASCII в строке Unicode. Не делайте этого, вы получите случайные исключения UnicodeEncodeError повсюду.
— Дуг

11
Этот ответ помог мне. Если вы знаете, что ваша строка ascii, и вам нужно привести ее обратно к не-юникодной строке, это очень полезно.
— ВедТопкар

113

Если у вас есть строка Unicode, и вы хотите записать ее в файл или другую сериализованную форму, вы должны сначала закодировать ее в определенное представление, которое можно сохранить. Существует несколько распространенных кодировок Unicode, таких как UTF-16 (для большинства символов Unicode используется два байта) или UTF-8 (1-4 байта / кодовая точка в зависимости от символа) и т. Д. Чтобы преобразовать эту строку в определенную кодировку, необходимо выполнить следующие действия. можешь использовать:

>>> s= u'£10'
>>> s.encode('utf8')
'\xc2\x9c10'
>>> s.encode('utf16')
'\xff\xfe\x9c\x001\x000\x00'

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

При записи в файлы вы можете избавиться от этого процесса кодирования / декодирования, используя модуль кодеков . Итак, чтобы открыть файл, который кодирует все строки Unicode в UTF-8 , используйте:

import codecs
f = codecs.open('path/to/file.txt','w','utf8')
f.write(my_unicode_string)  # Stored on disk as UTF-8

Обратите внимание, что все, кто использует эти файлы, должно понимать, в какой кодировке находится файл, если они хотят их прочитать. Если вы только читаете / пишете, это не проблема, в противном случае убедитесь, что вы пишете в форме, понятной для всех, кто использует файлы.

В Python 3 эта форма доступа к файлам используется по умолчанию, а встроенная openфункция принимает параметр кодирования и всегда переводит в / из строк Unicode (строковый объект по умолчанию в Python 3) для файлов, открытых в текстовом режиме.


58

Вот пример:

>>> u = u'€€€'
>>> s = u.encode('utf8')
>>> s
'\xe2\x82\xac\xe2\x82\xac\xe2\x82\xac'

1
Может кто-нибудь объяснить, почему, когда я кодирую символ евро, utf8как показано здесь, результатом являются только вопросительные знаки? Вот изображение моего Python, версия 2.7.13. (Я могу кодировать другие объекты Unicode, такие как u"Klüft", но не евро?)
— Red Pea

5

Что ж, если вы готовы / готовы перейти на Python 3 (что может не произойти из-за обратной несовместимости с некоторым кодом Python 2), вам не нужно делать никаких преобразований; Весь текст в Python 3 представлен строками Unicode, что также означает, что u'<text>'синтаксис больше не используется . У вас также есть, по сути, строки байтов, которые используются для представления данных (которые могут быть закодированной строкой).

http://docs.python.org/3.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit

(Конечно, если вы в настоящее время используете Python 3, проблема, скорее всего, связана с тем, как вы пытаетесь сохранить текст в файл.)


2
В Python 3 строки являются строками Unicode. Они никогда не кодируются. Я нашел следующий текст полезным: joelonsoftware.com/articles/Unicode.html

Он хочет сохранить это в файл; как ваш ответ поможет с этим?
— Джон Мачин

@lutz: Хорошо, я забыл, что Unicode - это карта символов, а не кодировка. @Джон: На ​​данный момент недостаточно информации, чтобы понять, в чем проблема с ее сохранением. Он получает ошибку? Он не получает никаких ошибок, но при внешнем открытии файла он получает моджибаке? Без этой информации существует слишком много возможных решений, которые могут быть предоставлены.
— JAB

@Cat: На данный момент нет никакой информации, чтобы знать, что у него есть, не говоря уже о том, какова его проблема спасения. Я попросил его предоставить некоторые факты - см. Мой ответ.
— Джон Мачин

5

Вот пример кода

import unicodedata    
raw_text = u"here $%6757 dfgdfg"
convert_text = unicodedata.normalize('NFKD', raw_text).encode('ascii','ignore')

чем этот ответ отличается от принятого ответа?
— Сгаури

3

файл содержит строку в юникоде

\"message\": \"\\u0410\\u0432\\u0442\\u043e\\u0437\\u0430\\u0446\\u0438\\u044f .....\",

для меня

 f = open("56ad62-json.log", encoding="utf-8")
 qq=f.readline() 

 print(qq)                          
 {"log":\"message\": \"\\u0410\\u0432\\u0442\\u043e\\u0440\\u0438\\u0437\\u0430\\u0446\\u0438\\u044f \\u043f\\u043e\\u043b\\u044c\\u0437\\u043e\\u0432\\u0430\\u0442\\u0435\\u043b\\u044f\"}

(qq.encode().decode("unicode-escape").encode().decode("unicode-escape")) 
# '{"log":"message": "Авторизация пользователя"}\n'

2
это работало, даже если я только использую:result.encode().decode('unicode-escape')
— Аммад Халид

0

Никакой ответ не работал для моего случая, где у меня была строковая переменная, содержащая символы Юникода, и никакой кодировки-декодирования, объясненные здесь, не помогли.

Если я делаю в терминале

echo "no me llama mucho la atenci\u00f3n"

или

python3
>>> print("no me llama mucho la atenci\u00f3n")

Вывод правильный:

output: no me llama mucho la atención

Но работа со скриптами, загружающими эту строковую переменную, не работала.

Вот что сработало в моем случае , на случай , если кто-нибудь поможет:

string_to_convert = "no me llama mucho la atenci\u00f3n"
print(json.dumps(json.loads(r'"%s"' % string_to_convert), ensure_ascii=False))
output: no me llama mucho la atención

вам нужно импортировать
— JSON
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.