Chuyển đổi một chuỗi Unicode thành một chuỗi trong Python (chứa các ký hiệu bổ sung)


504

Làm thế nào để bạn chuyển đổi một chuỗi Unicode (chứa các ký tự phụ như £ $, v.v.) thành chuỗi Python?


2
Chúng tôi cần biết bạn đang sử dụng phiên bản Python nào và bạn đang gọi chuỗi Unicode là gì. Thực hiện các thao tác sau trên unicode_ chuỗi ngắn bao gồm các ký hiệu tiền tệ gây phiền toái: Python 2.x: print type(unicode_string), repr(unicode_string)Python 3.x: print type(unicode_string), ascii(unicode_string)Sau đó chỉnh sửa câu hỏi của bạn và sao chép / dán kết quả của câu lệnh in ở trên. KHÔNG gõ lại kết quả. Đồng thời tìm kiếm gần đầu HTML của bạn và xem liệu bạn có thể tìm thấy thứ gì đó như thế này không: <meta http-Equiv = "Content-Type" content = "text / html; charset = iso-8859
John Machin

3
Tôi nghi ngờ rằng bạn nhận được unicode từ một yêu cầu web. Bạn có thể nhận được Unicode mã hóa UTF-8.

28
@lutz: chính xác thì "Unicode được mã hóa UTF-8" không phải là unicode như thế nào?
jalf

2
Bạn nên thực sự làm rõ ý của bạn bằng chuỗi unicodechuỗi python (đưa ra các ví dụ cụ thể sẽ là điều tốt nhất tôi đoán) vì rõ ràng từ các bình luận có nhiều cách hiểu khác nhau về câu hỏi của bạn. Tôi tự hỏi tại sao bạn chưa làm điều này mặc dù đã hơn 3,5 năm kể từ khi bạn hỏi câu hỏi này.
Piotr Dobrogost

6
@jalf: Nếu được mã hóa ; nó không còn là Unicode, vd,unicode_string = u"I'm unicode string"; bytestring = unicode_string.encode('utf-8'); unicode_again = bytestring.decode('utf-8')
jfs 21/12/13

Câu trả lời:


573

Xem 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 trả lời câu hỏi như đã nói, vấn đề của @ williamtroup về việc không thể lưu unicode vào một tệp có vẻ như là một vấn đề hoàn toàn khác xứng đáng với một câu hỏi riêng biệt
Mark Roddy

5
@ John - câu trả lời đó có trước sự làm rõ của OP.
Đaminh Rodger

10
@Mark Roddy: Câu hỏi của anh ấy như được viết là làm thế nào để chuyển đổi "chuỗi Unicode" (bất cứ điều gì anh ấy muốn nói) có chứa một số ký hiệu tiền tệ thành "chuỗi Python" (bất cứ điều gì ...) và bạn nghĩ rằng một loại bỏ dấu xóa các ký tự khác-không-ascii loại bỏ câu trả lời của mình ???
John Machin

13
@JohnMachin Điều này trả lời từ câu hỏi cho từ: Cách duy nhất để chuyển đổi một unicodechuỗi thành một strlà bỏ hoặc chuyển đổi các ký tự không thể được biểu thị trong ASCII. Vì vậy, +1 từ tôi.
Izkata

4
@lzkata: không, không phải vậy. type(title) == unicode and type(title.encode('utf-8')) == str. Không cần phải làm hỏng đầu vào, để có được một bytestring có thể được lưu vào một tệp.
jfs

319

Bạn có thể sử dụng mã hóa sang ASCII nếu bạn không cần dịch các ký tự không phải ASCII:

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

4
Câu trả lời tuyệt vời. Chính xác những gì tôi cần. Ngoài ra, bài thuyết trình tuyệt vời để cho thấy hiệu ứng của ignorevsreplace
Jonny Brooks

hoặc a.encode('ascii', 'xmlcharrefreplace')cho 'aaa&#224;&#231;&#231;&#231;&#241;&#241;&#241;'.
Bob Stein

type(a)strtrong Python 3.6.8 và không có bất kỳ encode()phương thức nào .
Ali Tou

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

Nếu chuỗi chỉ chứa ký tự ascii.


18
Điều này sẽ chỉ làm việc trên các cửa sổ. Và sẽ phá vỡ nếu có biểu tượng không phải ascii.
Vanuan

6
Điều này phá vỡ nếu nội dung của chuỗi thực sự là unicode, không chỉ các ký tự ascii trong chuỗi unicode. Đừng làm điều này, bạn sẽ nhận được các ngoại lệ UnicodeEncodeError ngẫu nhiên ở mọi nơi.
Doug

11
Câu trả lời này đã giúp tôi. Nếu bạn biết rằng chuỗi của bạn là ascii và bạn cần chuyển nó trở lại chuỗi không unicode, điều này rất hữu ích.
VedTopkar

113

Nếu bạn có một chuỗi Unicode và bạn muốn ghi nó vào một tệp, hoặc dạng nối tiếp khác, trước tiên bạn phải mã hóa nó thành một đại diện cụ thể có thể được lưu trữ. Có một số mã hóa Unicode phổ biến, chẳng hạn như UTF-16 (sử dụng hai byte cho hầu hết các ký tự Unicode) hoặc UTF-8 (1-4 byte / mã tùy thuộc vào ký tự), v.v. Để chuyển đổi chuỗi đó thành mã hóa cụ thể, bạn co thể sử dụng:

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

Chuỗi byte thô này có thể được ghi vào một tệp. Tuy nhiên, lưu ý rằng khi đọc lại, bạn phải biết mã hóa đó là gì và giải mã nó bằng cách sử dụng cùng mã hóa đó.

Khi ghi vào tệp, bạn có thể thoát khỏi quá trình mã hóa / giải mã thủ công này bằng cách sử dụng mô-đun codec . Vì vậy, để mở tệp mã hóa tất cả các chuỗi Unicode thành UTF-8 , hãy sử dụng:

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

Xin lưu ý rằng bất cứ điều gì khác đang sử dụng các tệp này phải hiểu mã hóa tệp là gì nếu họ muốn đọc chúng. Nếu bạn là người duy nhất thực hiện việc đọc / viết thì đây không phải là vấn đề, nếu không, hãy đảm bảo rằng bạn viết ở dạng dễ hiểu bởi bất cứ điều gì khác sử dụng các tệp.

Trong Python 3, hình thức truy cập tệp này là mặc định và openhàm tích hợp sẽ lấy tham số mã hóa và luôn dịch sang / từ chuỗi Unicode (đối tượng chuỗi mặc định trong Python 3) cho các tệp được mở ở chế độ văn bản.


58

Đây là một ví dụ:

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

1
Bất cứ ai có thể giải thích tại sao, khi tôi mã hóa biểu tượng Euro utf8như được hiển thị ở đây, kết quả chỉ là dấu chấm hỏi? Đây là hình ảnh về Python của tôi, phiên bản 2.7.13. (Tôi có thể mã hóa các đối tượng unicode khác như u"Klüft", nhưng không phải là Euro?)
The Red Pea

5

Chà, nếu bạn sẵn sàng / sẵn sàng chuyển sang Python 3 (mà bạn có thể không phải do không tương thích ngược với một số mã Python 2), bạn không phải thực hiện bất kỳ chuyển đổi nào; tất cả văn bản trong Python 3 được thể hiện bằng các chuỗi Unicode, điều đó cũng có nghĩa là không còn sử dụng u'<text>'cú pháp nữa. Bạn cũng có những chuỗi byte được sử dụng để biểu thị dữ liệu (có thể là một chuỗi được mã hóa).

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

(Tất nhiên, nếu bạn hiện đang sử dụng Python 3, thì vấn đề có thể xảy ra với cách bạn cố lưu văn bản vào một tệp.)


2
Trong Python 3 chuỗi là chuỗi Unicode. Chúng không bao giờ được mã hóa. Tôi thấy văn bản sau hữu ích: joelonsoftware.com/articles/Unicode.html

Anh ta muốn lưu nó vào một tập tin; Làm thế nào để câu trả lời của bạn giúp với điều đó?
John Machin

@lutz: Phải, tôi đã quên rằng Unicode là bản đồ ký tự chứ không phải là mã hóa. @ John: Hiện tại không có đủ thông tin để biết vấn đề với việc lưu nó là gì. Là anh ấy nhận được một lỗi? Có phải anh ta không nhận được bất kỳ lỗi nào, nhưng khi mở tệp bên ngoài, anh ta sẽ nhận được mojibake? Không có thông tin đó, có quá nhiều giải pháp khả thi có thể được cung cấp.
JAB

@Cat: Hiện tại không có bất kỳ thông tin nào để biết anh ấy có gì, chứ đừng nói đến vấn đề tiết kiệm của anh ấy là gì. Tôi đã yêu cầu anh ấy cung cấp một số sự thật - xem câu trả lời của tôi.
John Machin

5

Đây là một mã ví dụ

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

câu trả lời này khác với câu trả lời được chấp nhận như thế nào?
sgauri

3

tập tin chứa chuỗi unicode-esged

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

cho tôi

 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
nó hoạt động ngay cả khi tôi chỉ sử dụng:result.encode().decode('unicode-escape')
Ammad Khalid

0

Không có câu trả lời nào hoạt động cho trường hợp của tôi, trong đó tôi có một biến chuỗi chứa ký tự unicode và không giải mã được giải mã ở đây đã làm việc.

Nếu tôi làm trong Terminal

echo "no me llama mucho la atenci\u00f3n"

hoặc là

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

Đầu ra là chính xác:

output: no me llama mucho la atención

Nhưng làm việc với các tập lệnh tải biến chuỗi này không hoạt động.

Đây là những gì làm việc trong trường hợp của tôi , trong trường hợp giúp đỡ bất cứ ai:

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

bạn cần nhập json
pctripsesp
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.