【问题标题】:Convert raw byte string to Unicode without knowing the codepage beforehand在事先不知道代码页的情况下将原始字节字符串转换为 Unicode
【发布时间】:2013-05-09 19:11:23
【问题描述】:

当使用右键菜单上下文时,windows 将文件路径作为原始(字节)字符串类型传递。

例如:

path = 'C:\\MyDir\\\x99\x8c\x85\x8d.mp3'

我的应用程序中的许多外部包都需要unicode 类型的字符串,因此我必须将其转换为unicode

如果我们事先知道原始字符串的编码(在示例中为cp1255),那将很容易。但是我不知道世界各地的每台计算机将在本地使用哪种编码。

如何将string 转换为unicode?也许需要使用win32api

【问题讨论】:

  • ASCII 是一种始终可以转换为 Unicode 的编解码器;只是.decode('ASCII')。你的意思不是 ASCII 而是编码字节。
  • 您通常无法在不知道编码的情况下将字符串解码为 un​​icode。您的文本不是 ASCII 而是一些未知的编码。
  • 您的示例是 not cp1255,使用该编解码器解码失败。它也不是 UTF-16,这是令人惊讶的,因为这是 Windows 内部用于文件名的。
  • import locale; path.decode(locale.getpreferredencoding()) 可能有用吗?
  • 根据您的断言判断,这是cp1255(希伯来语),我尝试了其他一些编解码器;这实际上是cp856cp862;两者都将您提供的字节解码为:C:\MyDir\שלום.mp3

标签: python windows unicode rawbytestring


【解决方案1】:

不知道为什么您可能会得到 DOS 代码页 (862) 而不是 ANSI (1255) - 右键单击​​选项是如何设置的?

无论哪种方式 - 如果您需要在参数中接受任意 Unicode 字符,则无法通过 Python 2 的 sys.argv 来实现。此列表由 Win32 API (GetCommandLineA) 的非 Unicode 版本返回的字节填充,并且该编码绝不是 Unicode 安全的。

包括 Java 和 Ruby 在内的许多其他语言也在同一条船上。限制来自 Microsoft C 运行时对 C 标准库函数的实现。要修复它,可以在 Windows 上调用 Unicode 版本 (GetCommandLineW),而不是依赖跨平台标准库。 Python 3 可以做到这一点。

与此同时,对于 Python 2,您可以通过自己调用 GetCommandLineW 来实现,但这并不是特别漂亮。如果您想要 Windows 样式的参数拆分,也可以使用 CommandLineToArgvW。您可以使用 win32 扩展或简单的 ctypes 来做到这一点。

Example(尽管最好跳过将 Unicode 字符串编码回 UTF-8 字节的步骤)。

【讨论】:

    【解决方案2】:

    通常我使用自己的 util 函数将普通代码页安全转换为 unicode。对于读取默认操作系统编码,locale.getpreferredencoding 函数可能会有所帮助 (http://docs.python.org/2/library/locale.html#locale.getpreferredencoding)。

    通过迭代一些预定义的编码尝试转换为 unicode 的 util 函数示例:

    # coding: utf-8
    def to_unicode(s):
        if isinstance(s, unicode): return s
    
        from locale import getpreferredencoding
        for cp in (getpreferredencoding(), "cp1255", "cp1250"):
            try:
                return unicode(s, cp)
            except UnicodeDecodeError:
                pass
        raise Exception("Conversion to unicode failed")
        # or fallback like:
        # return unicode(s, getpreferredencoding(), "replace")
    
    print (to_unicode("addđšđč枎ŠĐ"))
    

    可以通过使用 unicode 函数参数 errors="replace" 来启用回退。参考http://docs.python.org/2/library/functions.html#unicode

    要转换回某些代码页,您可以查看this

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-20
      • 2013-09-24
      • 2011-12-20
      相关资源
      最近更新 更多