Перетворити рядок Unicode в рядок на Python (містить додаткові символи)


503

Як перетворити рядок 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-equiv = "Content-Type" content = "text / html; charset = iso-8859
John Machin

3
Я сумніваюся, що ви отримаєте unicode з веб-запиту. Ви пропонуєте отримати Unicode, кодований UTF-8.

28
@lutz: як саме "UTF-8 закодований Unicode" не є unicode?
jalf

2
Вам слід дійсно уточнити, що ви маєте на увазі під unicode string та python string (наведення конкретних прикладів було б найкращим, як я думаю), оскільки зрозуміло, що з коментарів є різні інтерпретації вашого питання. Цікаво, чому ви цього не робили, хоча минуло 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

Відповіді:


572

Подивитися 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 не в змозі зберегти unicode у файл звучить як зовсім інша проблема, гідна окремого питання
Марк Родді

5
@John - ця відповідь передує роз'ясненню ОП.
Домінік Роджер

10
@ Марк Родді: Його запитання, як написано, полягає в тому, як перетворити "рядок Unicode" (що б він не мав на увазі під цим), що містить деякі символи валюти, в "рядок Python" (що б там не було ...), і ви вважаєте, що видалити-деякі-діакритики delete-other-non-ascii персонажі хизуються відповідями на його питання ???
Джон Махін

13
@JohnMachin Це відповідає на запитання слово за словом: Єдиний спосіб перетворити unicodeрядок у a str- це скинути або перетворити символи, які не можуть бути представлені в ASCII. Тож +1 від мене.
Ізката

4
@lzkata: ні, це не так. type(title) == unicode and type(title.encode('utf-8')) == str. Не потрібно пошкоджувати вхід, щоб отримати атестатор, який можна зберегти у файл.
jfs

318

Ви можете використовувати кодування для 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
Це працювало б лише на windows. І зламається, якщо є символи, що не мають права.
Вануан

6
Це руйнується, якщо вміст рядка насправді є unicode, а не просто символами ascii в рядку unicode. Не робіть цього, ви отримаєте випадкові винятки UnicodeEncodeError всюди.
Дуг

11
Ця відповідь мені допомогла. Якщо ви знаєте, що ваш рядок є ascii, і вам потрібно повернути його до рядка unicode, це дуже корисно.
VedTopkar

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 - це карта символів, а не кодування. @John: На даний момент недостатньо інформації, щоб знати, в чому проблема з її збереженням. Він отримує помилку? Він не отримує помилок, але при відкритті файлу зовні він отримує mojibake? Без цієї інформації існує дуже багато можливих рішень, які можна було б надати.
JAB

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

5

Ось приклад коду

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

чим ця відповідь відрізняється від прийнятої відповіді?
sgauri

3

Файл містить рядок, урізаний unicode

\"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

У моєму випадку не працювало жодної анкети, де я мав змінну рядків, що містить символи unicode, і жодне кодування-декодування, пояснене тут, не спрацювало.

Якщо я буду в терміналі

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
pctripsesp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.