【问题标题】:Unicode encoding for filesystem in Mac OS X not correct in Python?Mac OS X中文件系统的Unicode编码在Python中不正确?
【发布时间】:2012-04-03 05:03:27
【问题描述】:

在 OS X 和 Python 中处理 Unicode 文件名有点困难。我试图在代码后面使用文件名作为正则表达式的输入,但文件名中使用的编码似乎与 sys.getfilesystemencoding() 告诉我的不同。取以下代码:

#!/usr/bin/env python
# coding=utf-8

import sys,os
print sys.getfilesystemencoding()

p = u'/temp/s/'
s = u'åäö'
print 's', [ord(c) for c in s], s
s2 = s.encode(sys.getfilesystemencoding())
print 's2', [ord(c) for c in s2], s2
os.mkdir(p+s)
for d in os.listdir(p):
  print 'dir', [ord(c) for c in d], d

它输出以下内容:

utf-8
s [229, 228, 246] åäö
s2 [195, 165, 195, 164, 195, 182] åäö
dir [97, 778, 97, 776, 111, 776] åäö

所以,文件系统编码是 utf-8,但是当我使用它对我的文件名 åäö 进行编码时,它与我创建一个具有相同字符串的目录名称不同。我希望当我使用我的字符串 åäö 创建一个目录并读回它的名称时,它应该使用与我直接应用编码相同的代码。

如果我们查看代码点 97、778、97、776、111、776,它基本上是带有变音符号的 ASCII 字符,例如o + ¨ = ö,这使它成为两个字符,而不是一个。如何避免这种差异,Python 中是否有与 OS X 的这种行为相匹配的编码方案,为什么 getfilesystemencoding() 没有给我正确的结果?

还是我搞砸了?

【问题讨论】:

  • 可以解决这些特定字符的问题,方法是对文件名字符串执行以下正则表达式以将它们转换为无变音符号的 unicode:`m_aa = re.compile(ur"a\u0308",re .I), m_ae = re.compile(ur"a\u030a",re.I), m_oe = re.compile(ur"o\u0308",re.I)

标签: python macos unicode file-io filesystems


【解决方案1】:

MacOS X 使用一种特殊的分解 UTF-8 来存储文件名。如果您需要,例如读入文件名并将它们写入“普通”UTF-8 文件,您必须对其进行规范化:

filename = unicodedata.normalize('NFC', unicode(filename, 'utf-8')).encode('utf-8')

从这里:https://web.archive.org/web/20120423075412/http://boodebr.org/main/python/all-about-python-and-unicode

【讨论】:

  • 在 node.js 中遇到了这个问题,npm 包 unorm 有一个非常好的接口。
【解决方案2】:

getfilesystemencoding() 给你正确的响应(编码),但它没有告诉你unicode normalisation form

特别是,HFS+ 文件系统使用 UTF-8 编码和接近“D”的规范化形式(需要将像 ö 这样的组合字符分解为 )。 HFS+ 也与 Unicode 版本 3.2 中存在的规范化形式相关联——详见 Apple 的documentation for the HFS+ format

Python 的unicodedata.normalize 方法在表单之间进行转换,如果在调用前加上ucd_3_2_0 对象,则可以将其限制为Unicode 版本3.2:

filename = unicodedata.ucd_3_2_0.normalize('NFC', unicode(filename, 'utf-8')).encode('utf-8')

【讨论】:

  • 谢谢,很好的答案,希望我能投票并接受这两个答案!
  • 其实也不是很NFD,但是很接近。
  • 如果HFS+以分解形式存储文件名,你不会使用normalise('NFD'...)来匹配HFS+编码吗?
猜你喜欢
  • 2010-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-30
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多