Преобразовать строку 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.