แปลงสตริง 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-equiv = "ประเภทเนื้อหา" เนื้อหา = "ข้อความ / html; charset = iso-8859
John Machin

3
ฉันสงสัยว่าคุณได้รับ Unicode จากคำขอทางเว็บ คุณจะได้รับ Unicode เข้ารหัส UTF-8

28
@lutz: ว่า "UTF-8 เข้ารหัส Unicode" ไม่ unicode อย่างไร
jalf

2
คุณควรอธิบายให้ชัดเจนว่าคุณหมายถึงอะไรโดยใช้ยูนิโค้ดสตริงและไพ ธ อนสตริง (ให้ตัวอย่างที่เป็นรูปธรรมจะดีที่สุดที่ฉันเดา) เนื่องจากชัดเจนจากความคิดเห็นที่มีการตีความคำถามของคุณแตกต่างกัน ฉันสงสัยว่าทำไมคุณยังไม่ได้ทำสิ่งนี้ถึงแม้ว่าจะนานกว่า 3,5 ปีแล้วที่คุณถามคำถามนี้
Piotr Dobrogost

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 ของการที่จะไม่สามารถที่จะบันทึก Unicode กับเสียงไฟล์เช่นปัญหาที่แตกต่างกันอย่างสิ้นเชิงที่คุ้มค่าของคำถามที่แยกต่างหาก
มาร์คร็อดดี

5
@John - คำตอบนั้นมาก่อนการชี้แจงของ OP
Dominic Rodger

10
@ Mark Roddy: คำถามของเขาเป็นลายลักษณ์อักษรคือวิธีการแปลง "Unicode string" (สิ่งที่เขาหมายถึงโดยที่) ที่มีสัญลักษณ์สกุลเงินบางส่วนเพื่อ "Python สตริง" (อะไรก็ตาม ... ) และคุณคิดว่าการเอาออกบางกำกับ อักขระลบอื่น ๆ ที่ไม่ใช่ ASCII kludge ตอบคำถามของเขา ???
John Machin

13
@JohnMachin คำตอบสำหรับคำถามสำหรับคำ: วิธีเดียวที่จะแปลงunicodeสตริงเป็น a strคือการปล่อยหรือแปลงอักขระที่ไม่สามารถแสดงใน ASCII +1 จากฉัน
Izkata

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
คำตอบที่ยอดเยี่ยม สิ่งที่ฉันต้องการ นอกจากนี้การนำเสนอที่ยอดเยี่ยมเพื่อแสดงผลของignorevsreplace
Jonny Brooks

หรือช่วยให้a.encode('ascii', 'xmlcharrefreplace') 'aaa&#224;&#231;&#231;&#231;&#241;&#241;&#241;'
Bob Stein

type(a)อยู่strใน Python 3.6.8 และไม่มีencode()วิธีการใด ๆ
Ali Tou

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

หากสตริงมีอักขระ ASCII เท่านั้น


18
สิ่งนี้จะทำงานบน windows เท่านั้น และจะแตกถ้ามีสัญลักษณ์ที่ไม่ใช่ ASCII
Vanuan

6
สิ่งนี้จะหยุดถ้าเนื้อหาของสตริงเป็นยูนิโค้ดจริงไม่ใช่แค่ตัวอักษร ASCII ในสตริง Unicode อย่าทำอย่างนี้คุณจะได้รับ UnicodeEncodeError แบบสุ่มทุกที่
Doug

11
คำตอบนี้ช่วยฉัน หากคุณรู้ว่าสตริงของคุณคือ ascii และคุณต้องการส่งสตริงกลับไปเป็นสตริงที่ไม่ใช่ยูนิโค้ดสิ่งนี้มีประโยชน์มาก
VedTopkar

113

ถ้าคุณมีสายอักขระ Unicode และคุณต้องการเขียนสิ่งนี้ลงในไฟล์หรือแบบฟอร์มต่อเนื่องอื่น ๆ คุณต้องเข้ารหัสเป็นตัวแทนที่สามารถจัดเก็บได้ มีการเข้ารหัส Unicode ทั่วไปหลายอย่างเช่น UTF-16 (ใช้สองไบต์สำหรับอักขระ Unicode ส่วนใหญ่) หรือ UTF-8 (1-4 ไบต์ / codepoint ขึ้นอยู่กับอักขระ) ฯลฯ หากต้องการแปลงสตริงนั้นเป็นการเข้ารหัสเฉพาะคุณ สามารถใช้:

>>> 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"ได้ แต่ไม่ใช่ยูโร)
The 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

เขาต้องการบันทึกลงในไฟล์ คำตอบของคุณช่วยได้อย่างไร
John Machin

@lutz: ใช่ฉันลืมไปว่า Unicode เป็นแผนที่ของตัวละครมากกว่าการเข้ารหัส @John: มีข้อมูลไม่เพียงพอที่จะรู้ว่าปัญหาในการบันทึกคืออะไร เขาได้รับข้อผิดพลาดหรือไม่? เขาไม่ได้รับข้อผิดพลาดใด ๆ แต่เมื่อเปิดไฟล์ภายนอกเขาจะได้รับ mojibake? หากไม่มีข้อมูลนั้นจะมีวิธีแก้ไขที่เป็นไปได้มากมายเกินกว่าที่จะจัดหาได้
JAB

@Cat: ไม่มีข้อมูลใด ๆ ที่จะรู้ว่าสิ่งที่เขามีในขณะนี้ปัญหาการออมของเขาคืออะไร ฉันขอให้เขาให้ข้อเท็จจริง - ดูคำตอบของฉัน
John Machin

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')
Ammad Khalid

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.