【问题标题】:Is there a way to find a character's Unicode code point in Python 2.7?有没有办法在 Python 2.7 中找到字符的 Unicode 代码点?
【发布时间】:2016-12-18 23:02:34
【问题描述】:

我在我的 Python 程序中使用国际音标 (IPA) 符号,这是一组相当奇怪的字符,其 UTF-8 代码的长度范围为 1 到 3 个字节。几年前的This thread 基本上问了相反的问题,似乎ord(character) 可以检索一个十进制数,我可以将其转换为十六进制,然后转换为代码点,但ord() 的输入似乎仅限于一个字节。如果我在任何非 ASCII 字符上尝试 ord(),例如 ɨ,它会输出:

TypeError: ord() expected a character, but a string of length 2 found

由于不再是选项,Python 2.7 中是否有任何方法可以找到给定字符的 Unicode 代码点? (那么该字符是否必须是 unicode 类型?)我的意思也不是仅在 Unicode 表上手动查找它。

【问题讨论】:

    标签: python python-2.7 unicode


    【解决方案1】:
    >>> u'ɨ'
    u'\u0268'
    >>> u'i'
    u'i'
    >>> 'ɨ'.decode('utf-8')
    u'\u0268'
    

    【讨论】:

      【解决方案2】:

      由于不再是选项,Python 2.7 中是否有任何方法可以找到给定字符的 Unicode 代码点? (那么该字符是否必须是 unicode 类型?)我的意思也不是仅在 Unicode 表上手动查找它。

      您只能找到 unicode 对象的 unicode 代码点。要将字节字符串转换为 unicode 对象,请使用 mystr.decode(encoding) 对其进行解码,其中 encoding 是字符串的编码。 (你知道你的字符串的编码,对吧?它可能是 UTF-8。:-) 然后你可以根据你已经找到的说明使用ord

      >>> ord(b"ɨ".decode('utf-8'))
      616
      

      顺便说一句,从您的问题看来,您正在使用 UTF-8 编码字节形式的字符串。那恐怕会很痛苦。您应该在获得字符串后立即将它们解码为 un​​icode 对象,并且仅在需要将它们输出到某处时才对其进行编码。

      【讨论】:

      • 嗨,BrenBarn,感谢您的回复,但它仍然提出相同的TypeError。我已经尝试了我所知道的一切来确保该字符以 UTF-8 开头,以便可以对其进行解码。当从文件中读取字符而不是像那样硬编码时,这种方法是否仍然有效?我有测试脚本here 和输入文件here。抱歉,如果这不是要求澄清的写作场所;我是 SO 的新人
      • @Arcaeca:您的错误可能是因为您正在从文件中读取字节,抓取一个字节,然后尝试对其进行解码。但是如果你抓取一个多字节 UTF-8 序列的一个字节,解码就会失败。正如我在回答中所说,您不应该尝试对单个字符进行编码和解码。在您读入文件时立即解码整个文件,例如使用io.open 而不是内置的打开函数。
      【解决方案3】:

      这实际上是 Python 2 中的一个错误,取决于它是如何构建的,用于 BMP 之外的 unicode 字符 (>= 0xFFFF);见:https://bugs.python.org/issue8670#msg105656

      例如这有效:

      >>> ord('\uffff')
      65535
      >>> len('\uffff')
      1
      

      但这不是:

      >>> ord(u'\U00010000')
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: ord() expected a character, but string of length 2 found
      

      更令人惊讶的是:

      >>> len(u'\U00010000')
      2
      

      这是因为 Python 曾经存在“窄”构建与“宽”构建。在“窄”构建中,Unicode 字符串在内部用 UCS2 表示(因此使用较少的内存,但必须使用两个 UCS2 字符(“代理对”)来表示 U+FFFF 以上的字符),而在“宽”构建中,UCS4 是内部用于 unicode 字符串,你不会有这个问题。

      在较新版本的 Python 3 中(我认为是从 3.2 或 3.3 开始,但我不记得了)这不再是问题,而且情况要好得多。最简单的检查方法是使用sys.maxunicode,在窄版本上将是0xffff

      This answer 演示了如何从窄构建中的代理对中提取序数。

      【讨论】:

      • Python3.3中UCS4的内部存储发生了变化
      猜你喜欢
      • 2023-04-02
      • 1970-01-01
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 2010-09-19
      • 1970-01-01
      相关资源
      最近更新 更多