Ubah string Unicode menjadi string dengan Python (berisi simbol tambahan)

504

Bagaimana Anda mengonversi string Unicode (berisi karakter tambahan seperti £ $, dll.) Ke string Python?

williamtroup
sumber
2
Kita perlu tahu versi Python apa yang Anda gunakan, dan apa yang Anda panggil string Unicode. Lakukan hal berikut pada unicode_string pendek yang menyertakan simbol mata uang yang menyebabkan gangguan: Python 2.x: print type(unicode_string), repr(unicode_string)Python 3.x: print type(unicode_string), ascii(unicode_string)Kemudian edit pertanyaan Anda dan salin / tempelkan hasil dari pernyataan cetak di atas. JANGAN mengetik ulang hasilnya. Lihat juga di dekat bagian atas HTML Anda dan lihat apakah Anda dapat menemukan sesuatu seperti ini: <meta http-equiv = "Content-Type" content = "text / html; charset = iso-8859
John Machin
3
Saya ragu Anda mendapatkan unicode dari permintaan web. Anda mungkin mendapatkan Unicode yang dikodekan UTF-8.
28
@ Lutz: bagaimana tepatnya "UTF-8 encode Unicode" tidak unicode?
jalf
2
Anda harus benar-benar menjelaskan apa yang Anda maksud dengan string unicode dan string python (memberikan contoh konkret akan menjadi yang terbaik yang saya kira) karena jelas dari komentar ada interpretasi yang berbeda dari pertanyaan Anda. Saya heran mengapa Anda belum melakukan ini meskipun sudah lebih dari 3,5 tahun sejak Anda mengajukan pertanyaan ini.
Piotr Dobrogost
6
@jalf: Jika dikodekan ; tidak lagi Unicode misalnya,unicode_string = u"I'm unicode string"; bytestring = unicode_string.encode('utf-8'); unicode_again = bytestring.decode('utf-8')
jfs

Jawaban:

573

Lihat 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'
Sorantis
sumber
24
+1 menjawab pertanyaan sebagai worded, masalah @ williamtroup karena tidak dapat menyimpan unicode ke file terdengar seperti masalah yang sama sekali berbeda yang layak untuk pertanyaan yang terpisah
Mark Roddy
5
@ John - jawaban itu mendahului klarifikasi OP.
Dominic Rodger
10
@ Mark Roddy: Pertanyaannya seperti yang tertulis adalah bagaimana mengkonversi "string Unicode" (apa pun maksudnya) yang berisi beberapa simbol mata uang menjadi "string Python" (apa pun ...) dan Anda berpikir bahwa remove-some-diacritics delete-other-non-ascii karakter kludge menjawab pertanyaannya ???
John Machin
13
@JohnMachin Ini menjawab kata per kata: Satu- satunya cara untuk mengonversi unicodestring menjadi a stradalah dengan menjatuhkan atau mengonversi karakter yang tidak dapat direpresentasikan dalam ASCII. Jadi +1 dari saya.
Izkata
4
@ lzkata: tidak, tidak. type(title) == unicode and type(title.encode('utf-8')) == str. Tidak perlu merusak input, untuk mendapatkan bytestring yang dapat disimpan ke file.
jfs
319

Anda dapat menggunakan penyandian ke ASCII jika Anda tidak perlu menerjemahkan karakter non-ASCII:

>>> a=u"aaaàçççñññ"
>>> type(a)
<type 'unicode'>
>>> a.encode('ascii','ignore')
'aaa'
>>> a.encode('ascii','replace')
'aaa???????'
>>>
Ferran
sumber
4
Jawaban yang luar biasa. Apa yang saya butuhkan. Juga, presentasi yang bagus untuk menunjukkan efek ignorevsreplace
Jonny Brooks
atau a.encode('ascii', 'xmlcharrefreplace')memberi 'aaa&#224;&#231;&#231;&#231;&#241;&#241;&#241;'.
Bob Stein
type(a)ada strdi Python 3.6.8 dan tidak memiliki encode()metode apa pun .
Ali Tou
138
>>> text=u'abcd'
>>> str(text)
'abcd'

Jika string hanya berisi karakter ascii.

igco
sumber
18
Ini hanya akan bekerja di windows. Dan akan pecah jika ada simbol non-ascii.
Vanuan
6
Ini rusak jika konten string sebenarnya unicode, bukan hanya karakter ascii dalam string unicode. Jangan lakukan ini, Anda akan mendapatkan pengecualian UnicodeEncodeError acak di semua tempat.
Doug
11
Jawaban ini membantu saya. Jika Anda tahu bahwa string Anda adalah ascii dan Anda perlu mengembalikannya ke string non-unicode, ini sangat berguna.
VedTopkar
113

Jika Anda memiliki string Unicode, dan Anda ingin menulis ini ke file, atau bentuk serial lainnya, Anda harus terlebih dahulu menyandikannya ke representasi tertentu yang dapat disimpan. Ada beberapa pengkodean Unicode umum, seperti UTF-16 (menggunakan dua byte untuk sebagian besar karakter Unicode) atau UTF-8 (1-4 byte / codepoint tergantung pada karakternya), dll. Untuk mengonversi string itu menjadi pengkodean tertentu, Anda bisa menggunakan:

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

String byte mentah ini dapat ditulis ke file. Namun, perhatikan bahwa ketika membacanya kembali, Anda harus tahu apa itu pengkodean dan mendekode menggunakan pengodean yang sama.

Saat menulis ke file, Anda dapat menyingkirkan proses encode / decode manual ini dengan menggunakan modul codec . Jadi, untuk membuka file yang mengkodekan semua string Unicode ke UTF-8 , gunakan:

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

Perhatikan bahwa segala hal lain yang menggunakan file-file ini harus memahami apa penyandian file jika ingin membacanya. Jika Anda adalah satu-satunya yang melakukan pembacaan / penulisan ini bukan masalah, jika tidak pastikan Anda menulis dalam bentuk yang dapat dimengerti oleh siapa pun yang menggunakan file tersebut.

Dalam Python 3, bentuk akses file ini adalah default, dan openfungsi bawaan akan mengambil parameter encoding dan selalu menerjemahkan ke / dari string Unicode (objek string default di Python 3) untuk file yang dibuka dalam mode teks.

Brian
sumber
58

Berikut ini sebuah contoh:

>>> u = u'€€€'
>>> s = u.encode('utf8')
>>> s
'\xe2\x82\xac\xe2\x82\xac\xe2\x82\xac'
Bastien Léonard
sumber
1
Adakah yang bisa menjelaskan mengapa, ketika saya menyandikan simbol Euro utf8seperti yang ditunjukkan di sini, hasilnya hanya tanda tanya? Ini adalah gambar Python saya, versi 2.7.13. (Saya dapat menyandikan objek unicode lain seperti u"Klüft", tetapi bukan Euro?)
The Red Pea
5

Nah, jika Anda bersedia / siap untuk beralih ke Python 3 (yang mungkin bukan karena ketidakcocokan mundur dengan beberapa kode Python 2), Anda tidak perlu melakukan konversi apa pun; semua teks dalam Python 3 diwakili dengan string Unicode, yang juga berarti bahwa tidak ada lagi penggunaan u'<text>'sintaksis. Anda juga memiliki apa, string byte, yang digunakan untuk merepresentasikan data (yang mungkin merupakan string yang disandikan).

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

(Tentu saja, jika Anda saat ini menggunakan Python 3, maka masalahnya kemungkinan ada hubungannya dengan bagaimana Anda mencoba menyimpan teks ke file.)

TUSUKAN
sumber
2
Dalam Python 3 string adalah string Unicode. Mereka tidak pernah dikodekan. Saya menemukan teks berikut berguna: joelonsoftware.com/articles/Unicode.html
Dia ingin menyimpannya ke file; Bagaimana jawaban Anda membantu hal itu?
John Machin
@ Lutz: Benar, saya lupa bahwa Unicode adalah peta karakter daripada penyandian. @ John: Saat ini tidak ada cukup informasi untuk mengetahui apa masalahnya dengan menyimpannya. Apakah dia mendapatkan kesalahan? Apakah dia tidak mendapatkan kesalahan, tetapi ketika membuka file secara eksternal dia mendapat mojibake? Tanpa informasi itu, ada terlalu banyak solusi yang mungkin dapat disediakan.
JAB
@Cat: Tidak ada informasi saat ini untuk mengetahui apa yang dia punya, apalagi masalah tabungannya. Saya sudah memintanya untuk memberikan beberapa fakta - lihat jawaban saya.
John Machin
5

Berikut ini contoh kode

import unicodedata    
raw_text = u"here $%6757 dfgdfg"
convert_text = unicodedata.normalize('NFKD', raw_text).encode('ascii','ignore')
Gihan Chathuranga
sumber
bagaimana jawaban ini berbeda dari jawaban yang diterima?
sgauri
3

file berisi string unicode-esaped

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

untuk saya

 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'
madjardi
sumber
2
itu bekerja bahkan jika saya hanya menggunakan:result.encode().decode('unicode-escape')
Ammad Khalid
0

Tidak ada jawaban yang berfungsi untuk kasus saya, di mana saya memiliki variabel string yang berisi karakter unicode, dan tidak ada kode-decode yang dijelaskan di sini.

Jika saya melakukannya di Terminal

echo "no me llama mucho la atenci\u00f3n"

atau

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

Outputnya benar:

output: no me llama mucho la atención

Tetapi bekerja dengan skrip yang memuat variabel string ini tidak berfungsi.

Inilah yang berhasil pada kasus saya , kalau-kalau membantu siapa pun:

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
pctripsesp
sumber
Anda perlu mengimpor json
pctripsesp