如何在Python中根据名称确定Unicode字符,即使该字符是控制字符?
我想在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 个回答
你可以自己制作一个“数据库”,来存储控制字符的信息,这个过程可以通过解析Unicode公共目录中的一些UCD文件来实现。特别是,可以查看UnicodeData-6.1.0d3这个文件(或者查看上级目录获取早期版本)。
我觉得在标准的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之禅所说,“实用胜于纯粹”。
Kerrek SB的评论很不错:直接把名字写在注释里就行了。
顺便说一下,Python也支持一种带名字的unicode字面量:
>>> u"\N{NO-BREAK SPACE}"
u'\xa0'
不过,它使用的是同样的unicode名称数据库,而控制字符并不在其中。