簡體   English   中英

Python UTF8編碼

[英]Python UTF8 encoding

我看過有關Python和編碼的其他問題,但還沒有找到解決我問題的方法。 這里是:

我有一個小腳本,試圖比較2個文件列表:

  1. 文本文件中給出的列表,應該以UTF8編碼(至少Notepad ++會這樣檢測到該列表)。

  2. 我建立的目錄清單如下:

     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規范化

現在,在Unicode中,有許多不同序列的實例在圖形和/或語義上是相同的,雖然將UTF-8流視為不透明的二進制序列通常是一個好主意,但是如果您想這樣做,則會帶來問題搜索或索引-尋找一個序列與另一個序列不匹配,即使它們在圖形和語義上是相同的。 因此,Unicode定義了四種類型的規范化 ,可用於“縮小”這種差異並從組合形式和分解形式中獲得相同的代碼點。 例如,在這種情況下,NFC和NFKC歸一化格式將為您的兩個序列提供0xe9代碼點,而NFD和NFKD將為0x65 0x301分解形式。

要在Python中執行此操作,您必須首先將UTF-8 str對象decodeunicode對象,然后使用unicodedata.normalize方法。

重要說明 :除非要實現“智能”索引編制/搜索,否則不要進行標准化,並且僅將標准化數據用於此目的-即標准化索引和搜索,但要向用戶存儲/提供原始格式。 規范化是一種有損操作(尤其是某些形式),盲目地將其應用於用戶數據就像在陶瓷店里用大錘進入一樣。

文件路徑

好的,這通常是關於Unicode的。 談論文件系統路徑既簡單又復雜。

原則上 ,Windows和Linux上幾乎所有常見的文件系統都將路徑視為不透明字符1序列(對目錄分隔符和可能的NUL字符進行模運算),沒有應用特定的規范化形式2 因此,在給定目錄中,您可以擁有兩個看起來相同但確實不同的文件名:

終端中名為é的兩個文件

因此,在原則上處理文件路徑時,您永遠不應規范化 -同樣,文件路徑是不透明的代碼點序列 (實際上,在Linux上是不透明的字節序列),不應混淆。

但是,如果您收到的列表和必須處理的列表進行了不同的規范化(這可能意味着它已通過損壞的軟件傳遞,可以“有幫助”地規范組成/分解的序列,或者手動輸入了名稱) ),則必須執行一些標准化匹配。

如果要處理類似的情況( 按定義划分 ),我將執行以下操作:

  • 首先嘗試完全匹配;
  • 如果失敗,則嘗試將標准化文件名與包含目錄標准化內容的set進行匹配; 請注意,如果將多個原始名稱映射到同一個標准化名稱, 您與之完全不匹配,則您將無法知道哪一個是“正確的名稱”。

腳注

  1. Linux本地文件系統都使用基於8位字節的路徑-內核可以在任何編碼下使用它們,而內核並不在乎,盡管最近的系統通常使用UTF-8。 Windows本地文件系統將改為使用16位基於單詞的路徑,這些路徑名義上包含UTF-16(最初為UCS-2)值。
  2. 在Windows上,在API級別上有點復雜,因為存在執行代碼頁轉換的整個ANSI API混亂,並且Win32路徑的不區分大小寫的匹配增加了更多級別的復雜性,但是在內核和文件系統級別上則完全不透明2個字節的WCHAR字符串。

在文件頂部添加這些

#!/usr/bin/env python
# -*- coding: utf-8 -*-

希望這可以幫助..!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM