[英]Python UTF8 encoding
我看過有關Python和編碼的其他問題,但還沒有找到解決我問題的方法。 這里是:
我有一個小腳本,試圖比較2個文件列表:
文本文件中給出的列表,應該以UTF8編碼(至少Notepad ++會這樣檢測到該列表)。
我建立的目錄清單如下:
local = [f.encode('utf-8') for f in listdir(dir) ]
但是,對於某些字符,我沒有得到相同的表示形式:在HEX編輯器中查看時,我發現在1中,字符é
由65 cc
給出,而在2中則由c3 a9
給出...
我想要的是使它們具有相同的編碼,無論它是什么。
您的第一個序列不完整cc
是兩字節UTF-8序列的前綴。 最有可能的是,整個序列是65 cc 81
,實際上是字符e
(0x65),后跟一個COMBINING ACUTE ACCENT (0x301,在UTF-8中表示為cc 81
)。
相反,另一個序列是帶有 ACUTE字符(0xe9,在UTF-8中表示為c3 a9
)的預組合拉丁文小寫字母E。 您會在鏈接的頁面中注意到其分解恰好是第一個序列。
現在,在Unicode中,有許多不同序列的實例在圖形和/或語義上是相同的,雖然將UTF-8流視為不透明的二進制序列通常是一個好主意,但是如果您想這樣做,則會帶來問題搜索或索引-尋找一個序列與另一個序列不匹配,即使它們在圖形和語義上是相同的。 因此,Unicode定義了四種類型的規范化 ,可用於“縮小”這種差異並從組合形式和分解形式中獲得相同的代碼點。 例如,在這種情況下,NFC和NFKC歸一化格式將為您的兩個序列提供0xe9代碼點,而NFD和NFKD將為0x65 0x301分解形式。
要在Python中執行此操作,您必須首先將UTF-8 str
對象decode
為unicode
對象,然后使用unicodedata.normalize
方法。
重要說明 :除非要實現“智能”索引編制/搜索,否則不要進行標准化,並且僅將標准化數據用於此目的-即標准化索引和搜索,但要向用戶存儲/提供原始格式。 規范化是一種有損操作(尤其是某些形式),盲目地將其應用於用戶數據就像在陶瓷店里用大錘進入一樣。
好的,這通常是關於Unicode的。 談論文件系統路徑既簡單又復雜。
原則上 ,Windows和Linux上幾乎所有常見的文件系統都將路徑視為不透明字符1序列(對目錄分隔符和可能的NUL字符進行模運算),沒有應用特定的規范化形式2 。 因此,在給定目錄中,您可以擁有兩個看起來相同但確實不同的文件名:
因此,在原則上處理文件路徑時,您永遠不應規范化 -同樣,文件路徑是不透明的代碼點序列 (實際上,在Linux上是不透明的字節序列),不應混淆。
但是,如果您收到的列表和必須處理的列表進行了不同的規范化(這可能意味着它已通過損壞的軟件傳遞,可以“有幫助”地規范組成/分解的序列,或者手動輸入了名稱) ),則必須執行一些標准化匹配。
如果要處理類似的情況( 按定義划分 ),我將執行以下操作:
set
進行匹配; 請注意,如果將多個原始名稱映射到同一個標准化名稱, 而您與之完全不匹配,則您將無法知道哪一個是“正確的名稱”。 WCHAR
字符串。 在文件頂部添加這些
#!/usr/bin/env python
# -*- coding: utf-8 -*-
希望這可以幫助..!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.