Soy*_*cis 2 python encoding utf-8
我看过有关Python和编码的其他问题,但还没有找到解决我问题的方法。这里是:
我有一个小脚本,试图比较2个文件列表:
文本文件中给出的列表,应该以UTF8编码(至少Notepad ++会这样检测到该列表)。
我建立的目录清单如下:
local = [f.encode('utf-8') for f in listdir(dir) ]
Run Code Online (Sandbox Code Playgroud)但是,对于某些字符,我没有得到相同的表示形式:在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,以c3 a9UTF-8 表示)的预组合拉丁文小写字母E。您会在链接的页面中注意到其分解恰好是第一个序列。
现在,在Unicode中,有许多不同序列的实例在图形和/或语义上是相同的,虽然将UTF-8流视为不透明的二进制序列通常是一个好主意,但是如果您想这样做,则会带来问题搜索或索引-寻找一个序列与另一个序列不匹配,即使它们在图形和语义上是相同的。因此,Unicode定义了四种类型的规范化,可用于“平化”这种差异并从组合形式和分解形式中获得相同的代码点。例如,在这种情况下,NFC和NFKC归一化格式将为您的两个序列提供0xe9代码点,而NFD和NFKD将为0x65 0x301分解形式。
要在Python中执行此操作,您首先需要decode将UTF-8 str对象转换为unicode对象,然后再使用unicodedata.normalize方法。
重要说明:除非您正在实现“智能”索引/搜索,否则不要进行标准化,并且仅将标准化数据用于此目的-即对标准化的索引和搜索,但要向用户存储/提供原始格式。规范化是一种有损操作(尤其是某些形式),盲目地将其应用于用户数据就像在陶瓷店里用大锤进入一样。
好的,这通常是关于Unicode的。谈论文件系统路径既简单又复杂。
原则上,Windows和Linux上几乎所有常见的文件系统都将路径视为不透明字符1序列(对目录分隔符和可能的NUL字符进行模运算),没有应用特定的规范化形式2。因此,在给定目录中,您可以拥有两个看起来相同但确实不同的文件名:
因此,在原则上处理文件路径时,您永远不要规范化 -同样,文件路径是不透明的代码点序列(实际上,在Linux上是不透明的字节序列),不应混淆。
但是,如果您收到的列表和要处理的列表进行了不同的规范化(这可能意味着该列表已通过损坏的软件传递,可以“有帮助”地规范组成/分解的序列,或者手动输入了名称) ),则必须执行一些标准化匹配。
如果要处理类似的情况(按定义划分),我将执行以下操作:
set包含目录标准化内容的进行匹配;请注意,如果多个原始名称映射到相同的规范化名称,而您与之完全不匹配,则您将无法知道哪一个是“正确的名称”。WCHAR字符串。