要回答您的问题,我们需要检查几层 Unicode。
有效的 Unicode 代码点是从 0 到 U+10FFFF。您可能会发现unicodedata.category(char)
哪个类别具有 Unicode 代码点。
从 U+D800 到 U+DFFF 的值是代理项,不应使用它们(并且它们不能在 UTF-16 中编码/解码)。[它们用于将 UCS-2(如此古老的 Unicode,直到 U+FFFF 的代码点)增强到 UTF-16(到 U+10FFFF)。旧程序/语言(如 Javascript)可能使用两个代理表示,而不是一个 UTF-16 代码点]。
注意:Python 允许它们是因为surrogateescape(主要用于读取 sys.argv),但您应该忽略它们,但只能在内部使用它们,然后才能正确转换它们。
因此,请勿尝试使用此类代码。
还有非字符:U+FDD0–U+FDEF,以及 FFFE 或 FFFF(即 U+FFFE、U+FFFF、U+1FFFE、U+1FFFF、... U+10FFFE、U+10FFFF)[来自维基百科, Unicode ],不应该使用,但是 ev。BOM (U+FEFF),但在这种情况下仅作为第一个字符。原因:第一块:非字符 U+FDD0 到 U+FDEF 的目的是什么?,其他:自动检测编码,所以我们不应该有混淆的代码点:如果你检测到它们,你知道你使用了错误的编码,你改变了编码,直到你得到一个有效的第一个代码点。
现在,使用unicodedata.category(char)
,您还可以获得代码的类别(请参阅Unicode 字符类别)。直到 U+1F 和 U+7F–U+9F 的字符都是控制字符,不要打印它们。
您可能有格式化字符,这可能会修改附近的字符。
因此,您可能希望排除C*
(注意:这将丢弃所有上述字符)以及Z*
(空格)字符类别。
所以你有unicodedata
标准模块已知的可打印字符。用于unicodedata.unidata_version
检查数据库更新的 unicode 版本。你可能会。允许Cn
类别(未分配):也许现在它们已分配。
但这还不够。您需要一种字体来显示这些字符。谷歌有“No Tofu fonts”,这是(我认为)最完整的字体。
但这还不够。你只得到字符的标准表示(可能不会,你应该在每个字符之后添加一个 U+200C (ZWNJ),以强制字体不加入字符(例如在印度语言中)。但是你错过了所有的字符它们由代码点的组合表示:例如,许多重音字符、用圆圈或正方形包围的字符、国家标志(您需要按正确顺序排列的两个国家代码字符)等。
注意:我很好奇如何从字体文件中获取所有字形,但这不是你的问题。
附录:
我忘了说:组合字符不能单独显示,所以你需要在eg前面加上U+25CC,你可以检查它们unicodedata.combining(chr)
。
所以你可以使用这个代码
# if your console is not UTF-8 (or any unicode encoding) and python
# do no get it, you will get garbage
import unicodedata
combining = '\u25cc'
placeholder = '\ufffd'
zwnj = '\u200c'
line = ''
for code in range(0x10FFFF+1):
c = chr(code)
cat = unicodedata.category(c)
if cat.startswith('C'): # and cat != 'Cn':
r = placeholder
elif cat.startswith('Z'):
r = ' '
elif unicodedata.combining(c) > 0:
r = combining + c + zwnj
else:
r = c + zwnj
line += r
if code % 256 == 255:
print(line)
line = ''