判断一个字符是简体字还是繁体字。
Unicode 范围
开始以为可以用 Unicode 范围来表示,了解后发现简繁之间在 Unicode 字符集中位置存在交集,并且不是连续的,没办法用这种方法搞定。
如果真要靠这种办法,需要在茫茫字表中进行超级详细和繁杂的范围指定。
看到叶典网有一个字符集范围,但没有区分简繁。
Golang 也有一个 unicode.Han
,也没有区分简繁。
Unihan_Variants.txt
在 http://www.unicode.org/Public/UCD/latest/ucd/ 下载 Unihan.zip
,打开里面的 Unihan_Variants.txt
。
比如「战斗」的「斗」(繁体是「鬥」)这两行:
「斗」是 U+6597
,「鬥」是 U+9B25
。
U+6597 kTraditionalVariant U+9B25
U+9B25 kSimplifiedVariant U+6597
-
kTraditionalVariant
前面是简体专用,后面是繁体专用; -
kSimplifiedVariant
前面是繁体专用,后面是简体专用。
另外有「后U+540E、後U+5F8C」这种的字,「皇后」是简繁体通用,但表示 behind 时,简体用「后面」,繁体用「後面」。
所以就有以下这些行:
U+540E kSimplifiedVariant U+540E
U+5F8C kSimplifiedVariant U+540E
U+540E kTraditionalVariant U+540E U+5F8C
------- 翻译一下: -------
后 kSimplifiedVariant 后
後 kSimplifiedVariant 后
后 kTraditionalVariant 后 後
这种一对多、多对一的转换,除了「后/後」,还有「干/幹」等。
还有 kSpecializedSemanticVariant
这种「井/丼」的。
还有 kSpoofingVariant
这种欺骗性变体,比如「胶 U+80F6」和「㬵 U+3B35」不是同一个字。
参照 http://www.unicode.org/reports/tr38/#SCTC 查看各种标记的说明。
用不到这么精细的,不过这是个好工具啊,以后可能会用到。
自己弄个简体字表
适合简单的场景。
比如《通用汉字规范表》,但只有 8105 个字,并没有涵盖全部的简体字,比如「肏」「屄」「〇」「屌」「囧」等等很多字不在其中。
但《通用汉字规范表》缺失了大量生僻字,比如一大堆以鸟字旁、鱼字旁做为偏旁的汉字,不知道去哪里找到比较全面的字表。
opencc
如果不是太严谨的需求,临时使用的脚本等,可以考虑这个。
用 opencc 做简繁转换,然后对比原字符。
示例,判断字符是否为繁体字:
把字符进行繁转简。
c1
和繁转简后一致,则 c1
是简体字;
c2
和繁转简后不同,则 c2
是繁体字。
import opencc
converter = opencc.OpenCC('t2s.json') # 繁体→简体
c1 = '门'
print(c1 == converter.convert(c1)) # '门' == '门' True
c2 = '門'
print(c2 == converter.convert(c2)) # '門' != '门' False
但并不完全成功:
import opencc
converter = opencc.OpenCC('t2s.json') # 繁体→简体
for _, c in enumerate(['鴞', '鶲', '鮡', '鮠', '鮣', '鮋', '鮈', '鮊', '鰺', '鰏', '鰟']):
print(c+' -> '+converter.convert(c))
if c == converter.convert(c):
print(c)
# 鴞 -> 鸮
# 鶲 -> 鹟
# 鮡 -> 鮡
# 鮡
# 鮠 -> 鮠
# 鮠
# 鮣 -> 䲟
# 鮋 -> 鲉
# 鮈 -> 鮈
# 鮈
# 鮊 -> 鲌
# 鰺 -> 鲹
# 鰏 -> 鲾
# 鰟 -> 鳑
试了一些超冷门的字,如「鮡 鮠 鮈」并没有被转换为「𬶐 𬶏 𬶋」。
另外还有一些问题,如「乾」会被识别为繁体字,转换为「干」。