为什么unicodedata不识别某些字符?

22 投票
1 回答
2564 浏览
提问于 2025-04-18 11:59

在Python 2.7中,unicodedata.name()这个函数不能识别某些字符。

>>> from unicodedata import name
>>> name(u'\n')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: no such name
>>> name(u'a')
'LATIN SMALL LETTER A'

确实,Unicode中包含了字符\n,它有一个名字,叫做“换行符”。

注意,使用unicodedata.lookup('LINE FEED')unicodedata.lookup(u'LINE FEED')这两个方法都会出现KeyError: undefined character name的错误。

1 个回答

19

unicodedata.name() 这个查找功能是基于标准中的 UnicodeData.txt 数据库 的第二列(Python 2.7 使用的是 Unicode 5.2.0)。

如果这个名字是以 < 开头的,就会被忽略。所有的控制字符,包括换行符,都属于这一类;在第一列中,除了 <control> 之外,没有其他名字:

000A;<control>;Cc;0;B;;;;;N;LINE FEED (LF);;;;

第十列是 旧版 的 Unicode 1.0 名称,根据标准,这个名字是不应该使用的。换句话说,\n 除了通用的 <control> 外,没有其他名字,而 Python 数据库会忽略这个名字(因为它不唯一)。

Python 3.3 增加了对 NameAliases.txt 的支持,这样你可以通过别名来查找名字;所以 lookup('LINE FEED')lookup('new line')lookup('eol') 等等,都是指向 \n。不过,unicodedata.name() 方法不支持别名,也无法支持(那它该选哪个呢?):

  • 增加了对 Unicode 名称别名和命名序列的支持。现在 unicodedata.lookup()'\N{...}' 都可以解析名称别名,unicodedata.lookup() 也能解析命名序列。

总结一下:LINE FEED 不是 \n 的官方名称,它只是一个别名。从 Python 3.3 开始,你可以通过别名来查找字符。

撰写回答