您需要将 UTF-8 文件作为 UTF-32 代码点序列读取。例如:
std::shared_ptr<FILE> f(fopen(filename, "r"), fclose);
uint32_t c = 0;
while (utf8_read(f.get(), c))
{
if (is_english_char(c))
...
else if (is_cjk_char(c))
...
else
...
}
哪里utf8_read
有签名:
bool utf8_read(FILE *f, uint32_t &c);
现在,utf8_read
可能会读取 1-4 个字节,具体取决于第一个字节的值。请参阅http://en.wikipedia.org/wiki/UTF-8,谷歌搜索算法或使用您已经可用的库函数。
使用 UTF-32 代码点,您现在可以检查范围。对于英语,您可以检查它是 ASCII ( c < 0x7F
) 还是Latin
字符(包括对从例如法语导入的单词的重音字符的支持)。您可能还想排除不可打印的控制字符(例如0x01
)。
对于Latin
和/或CJK
字符检查,您可以检查字符是否在给定的代码块中(有关代码点范围,请参见http://www.unicode.org/Public/UNIDATA/Blocks.txt )。这是最简单的方法。
如果您正在使用支持 Unicode 且具有书写脚本检测功能的库(例如 glib 库),您可以使用脚本类型来检测字符。或者,您可以从http://www.unicode.org/Public/UNIDATA/Scripts.txt获取数据:
Name : Code : Language(s)
=========:===========:========================================================
Common : Zyyy : general punctuation / symbol characters
Latin : Latn : Latin languages (English, German, French, Spanish, ...)
Han : Hans/Hant : Chinese characters (Chinese, Japanese)
Hiragana : Hira : Japanese
Katakana : Kana : Japanese
Hangul : Hang : Korean
注意:脚本代码来自http://www.iana.org/assignments/language-subtag-registry ( Type == 'script'
)。