【问题标题】:Printing unicode character NAMES - e.g. 'GREEK SMALL LETTER ALPHA' - instead of 'α'打印 unicode 字符名称 - 例如'希腊小写字母 ALPHA' - 而不是 'α'
【发布时间】:2021-09-10 04:06:24
【问题描述】:

我正在测试函数isprintable()。我想打印字符串string.whitespace + unicodedata.lookup("GREEK SMALL LETTER ALPHA")中所有字符的Unicode NAMES。

如何打印所有名称 - 例如'SPACE'、'NO-BREAK SPACE'、HORIZONTAL TAB、'GREEK SMALL LETTER ALPHA。

import unicodedata, string

for e in string.whitespace + unicodedata.lookup("GREEK SMALL LETTER ALPHA"):
    print(ord(e))
    print(unicodedata.name(e))

我收到错误“ValueError:没有这样的名称”

32
SPACE
9
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
ValueError: no such name

【问题讨论】:

标签: python unicode python-unicode


【解决方案1】:

正如 cmets 所指出的,Unicode 数据库没有每个字符的名称,但 NameAliases.txt 有。下面解析该文件并返回一个别名(如果存在)。在这种情况下,文件中找到的第一个:

import string
import requests
import unicodedata as ud

# Pull the official NameAliases.txt from the matching Unicode database
# the current Python was built with.
response = requests.get(f'http://www.unicode.org/Public/{ud.unidata_version}/ucd/NameAliases.txt')

# Parse NameAliases.txt, storing the first instance of a code and a name
aliases = {}
for line in response.text.splitlines():
    if not line.strip() or line.startswith('#'):
        continue
    code,name,_ = line.split(';')
    val = chr(int(code,16))
    if val not in aliases:
        aliases[val] = name

# Return the first alias from NameAliases.txt if it exists when unicodedata.name() fails.
def name(c):
    try:
        return ud.name(c)
    except ValueError:
        return aliases.get(c,'<no name>')

for e in string.whitespace + ud.lookup("GREEK SMALL LETTER ALPHA"):
    print(f'U+{ord(e):04X} {name(e)}')

输出:

U+0020 SPACE
U+0009 CHARACTER TABULATION
U+000A LINE FEED
U+000D CARRIAGE RETURN
U+000B LINE TABULATION
U+000C FORM FEED
U+03B1 GREEK SMALL LETTER ALPHA

【讨论】:

    【解决方案2】:

    正如wjandreacomments 中链接的Q&A 中所述,ASCII 控制字符在当前的 Unicode 标准中没有正式名称,因此当您尝试查找它们时会收到 ValueError。

    标准库中的 curses.ascii 模块为这些字符提供了一个包含两个字符“名称”的列表,对应于 ASCII 表中 Char 列中列出的名称(由 man ascii 显示),但没有描述。

    所以我们可以这样做

    import string
    import unicodedata
    from curses.ascii import controlnames
    
    for e in (string.whitespace + "\N{GREEK SMALL LETTER ALPHA}"):
        try:
            name = unicodedata.name(e)
        except ValueError:
            name = controlnames[ord(e)]
        print(name)
    

    给出这个结果

    SPACE
    HT
    LF
    CR
    VT
    FF
    GREEK SMALL LETTER ALPHA
    

    这并不理想,但可能是在不使用外部资源的情况下可以做到的最好的,就像在this 出色的答案中所做的那样。

    【讨论】:

      猜你喜欢
      • 2019-07-16
      • 2020-03-07
      • 2021-07-27
      • 2017-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多