如何在Python中根据名称确定Unicode字符,即使该字符是控制字符?

10 投票
7 回答
1602 浏览
提问于 2025-04-16 20:54

我想在JavaScript中创建一个数组,这个数组包含所有表示空白的Unicode编码点(不包括我另外处理的Unicode空白编码点)。这些字符包括水平制表符、垂直制表符、换页符、空格、非断行空格和字节顺序标记(BOM)。我可以用一些神秘的数字来实现:

whitespace = [0x9, 0xb, 0xc, 0x20, 0xa0, 0xfeff]

不过这样有点晦涩,使用名字会更好。通过unicodedata.lookup方法和ord结合使用可以稍微帮助一下:

>>> ord(unicodedata.lookup("NO-BREAK SPACE"))
160

但是这对0x9、0xb或0xc不起作用——我想是因为它们是控制字符,而“换页符”等名字只是别名。有没有办法在标准Python中将这些“名字”映射到字符或它们的编码点上?还是说我没戏了?

7 个回答

2

你可以自己制作一个“数据库”,来存储控制字符的信息,这个过程可以通过解析Unicode公共目录中的一些UCD文件来实现。特别是,可以查看UnicodeData-6.1.0d3这个文件(或者查看上级目录获取早期版本)。

2

我觉得在标准的Python中是做不到的。unicodedata模块使用的是UnicodeData.txt v5.2.0这个Unicode数据库。注意,所有控制字符的名字都被标记为<control>(这是第二个字段,用分号分隔)。

在Python的源代码中,有一个脚本Tools/unicode/makeunicodedata.py,它用来生成Python运行时使用的表格。makeunicodename这个函数看起来是这样的:

def makeunicodename(unicode, trace):

    FILE = "Modules/unicodename_db.h"

    print "--- Preparing", FILE, "..."

    # collect names
    names = [None] * len(unicode.chars)

    for char in unicode.chars:
        record = unicode.table[char]
        if record:
            name = record[1].strip()
            if name and name[0] != "<":
                names[char] = name + chr(0)
    ...

注意,它会跳过那些名字以"<"开头的条目。因此,没有任何名字可以传递给unicodedata.lookup,从而返回那些控制字符。

你可以直接写出水平制表符、换行符和回车符的代码点,并加上说明性的注释。正如Python之禅所说,“实用胜于纯粹”。

13

Kerrek SB的评论很不错:直接把名字写在注释里就行了。

顺便说一下,Python也支持一种带名字的unicode字面量:

>>> u"\N{NO-BREAK SPACE}"
u'\xa0'

不过,它使用的是同样的unicode名称数据库,而控制字符并不在其中。

撰写回答