/ / Python: очистити рядок для Unicode? [дублікат] - python, unicode, кодування символів

Python: очистити рядок для Unicode? [дублікат] - python, unicode, кодування символів

Можливі дублікати:
Python UnicodeDecodeError - Я неправильно кодую?

У мене є рядок, який я намагаюся зробити безпечно для unicode() функція:

>>> s = " foo “bar bar ” weasel"
>>> s.encode("utf-8", "ignore")

Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
s.encode("utf-8", "ignore")
UnicodeDecodeError: "ascii" codec can"t decode byte 0x93 in position 5: ordinal not in range(128)
>>> unicode(s)

Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
unicode(s)
UnicodeDecodeError: "ascii" codec can"t decode byte 0x93 in position 5: ordinal not in range(128)

Я в основному плачу тут навколо. Що мені потрібно зробити, щоб видалити небезпечні символи з рядка?

Дещо пов'язано з цим питання, хоча я і сам не зміг вирішити мою проблему.

Це також не вдається:

>>> s
" foo x93bar bar x94 weasel"
>>> s.decode("utf-8")

Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
s.decode("utf-8")
File "C:Python25254libencodingsutf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: "utf8" codec can"t decode byte 0x93 in position 5: unexpected code byte

Відповіді:

37 для відповіді № 1

Хороше питання. Проблеми кодування є складними. Почнемо з "У мене є рядок". Струни в Python 2 не "дійсно" струни "вони "повторюють байтове масиви.Таким чином, ваш рядок, звідки він прийшов і яке кодування це в? Ваш приклад показує кучерявий цитати в буквальному, і я навіть не впевнений, як ви це зробили. Я намагаюся вставити його в інтерпретатор Python або набрати його в ОС X з Option- [, і воно не проходить.

Дивлячись на ваш другий приклад, хоча, у вас є характер шістнадцяткового 93. Це не може бути utf-8, оскільки в utf-8 є будь-який байт вище 127частина багатобайтової послідовності. Тому я гадаю, що він повинен бути латинським-1. Проблема полягає в тому, що x93 не є символом у наборі символів латиниці 1. Такий "невірний" діапазон у латинській-1 від x7f до x9f, який вважається незаконним, проте Microsoft бачив цей невикористаний діапазон і вирішив поставити "Кучеряві котирування" там, створюючи таке схоже кодування, яке називається "windows-1252", що на кшталт латиниця-1 з матеріалами в цьому невірному діапазоні.

Отже, припустімо, що це таке windows-1252. Що тепер? String.decode перетворює байти в Unicode, так що "це той, який ви хочете. Ваш другий приклад був на правильному шляху, але він не вдалося, тому що рядок не був" t utf-8. Спробуйте:

>>> uni = "foo x93bar barx94 weasel".decode("windows-1252")
u"foo u201cbar baru201d weasel"
>>> print uni
foo “bar bar” weasel
>>> type(uni)
<type "unicode">

Це правильно, тому що відкриття фігурної цитати єUnicode U + 201C. Тепер, коли ви маєте Unicode, ви можете серіалізувати його в байтах у будь-якому вибраному вами кодуванні (якщо вам потрібно передавати його по проводу) або просто зберегти його як Unicode, якщо він залишиться в Python.Якщо ви хочете перетворити на utf- 8, використовуйте функцію oppose, string.encode.

>>> uni.encode("utf-8")
"foo xe2x80x9cbar bar xe2x80x9d weasel"

Кучерявий котирування займає 3 байти для кодування в utf-8. Ви можете використовувати UTF-16, і вони можуть бути лише двома байтами. Ви не можете кодувати як ASCII, так і Latin-1, оскільки вони не мають фігурних котирувань.


4 для відповіді № 2

РЕДАГУВАТИ. Схоже, ваш рядок закодований таким чином, що (ЛИСТА ДВОЙНА ЦІНОВА МАРКА) стає x93 і (ПРАВИЙ ДВОЙНИЙ ЦІННИЙ ЗНАК) стає x94. Існує декілька кодових сторінок із таким відображенням, CP1250 є одним з них, тому ви можете використовувати це:

s = s.decode("cp1250")

Для всіх кодів сторінок, які мають карту до x93 побачити тут (всі вони також карту до x94, який можна перевірити тут)