迭代utf-8中的字符块

时间:2013-06-16 13:45:49

标签: c++ utf-8 locale icu

我的任务是迭代对应于给定语言(语言环境)的所有utf-8字符代码。我想这不是那么容易,我必须迭代字符块(例如,像“ru_RU”的整个cyrilic)。我可以在维基页面上找到字符块https://en.wikipedia.org/wiki/UTF-8,但我希望有更好的方法,而不是发明自己的自行车。

我看过icu-project,但我无法弄清楚我是否可以做我需要的事情。

我希望得到的结果是这样的:

for (unsignet int=UBLOCK_GREEK_EXTENDED; i<UBLOCK_GREEK_EXTENDED_SIZE; i++) {
    // do stuff
}

icu-project是一个非常强大的工具,所以我希望有人知道如何做到这一点:)

更新 我正在为移动设备的3D框架开发本地化选项。它会对truetype字体进行栅格化和编码,以便通过从栅格化字体文件中选择所需的图像来轻松渲染它们。由于我不得不关心内存量,我想在不同的文件中拆分光栅化字体用于不同的语言环境(或语言,或者像cirylic或greek这样的字符块),所以我不必将整个utf-8字体保存在内存中检测区域设置后只会加载相应的文件。

谢谢!

4 个答案:

答案 0 :(得分:1)

所以,我最终资助了如何正确使用icu-project库http://site.icu-project.org

这是一个示例解决方案。您可以指定语言环境或语言,并获取包含相对于语言环境/语言的符号的utf-8字符块数组。然后,您可以为每个字符块启动和结束。

UErrorCode err = U_ZERO_ERROR;
const int32_t capacity = 10;
const char* shortname = NULL;
int32_t num, j;
int32_t strLength = 4;
UScriptCode script[10] = {USCRIPT_INVALID_CODE};
num = uscript_getCode("en", script, capacity, &err);
UnicodeString temp = UnicodeString("[", 1, US_INV);
UnicodeString pattern;
for(j=0; j<num; j++) {
    shortname = uscript_getShortName(script[j]);
    UnicodeString str(shortname, strLength, US_INV);
    temp.append("[:");
    temp.append(str);
    temp.append(":]+");
}
pattern = temp.remove(temp.length()-1,1);
pattern.append("]");

UnicodeSet cnvSet(pattern, err);
printf("Number of script code associated are : %d \n", num);
printf("Range count: %d\n", cnvSet.getRangeCount());
printf("Set size: %d\n", cnvSet.size());
for(int32_t i=0; i<cnvSet.getRangeCount(); i++) {
    printf("Range start: %x\n", cnvSet.getRangeStart(i));
    printf("Range end: %x\n", cnvSet.getRangeEnd(i));
}

此示例中语言“en”的结果:

  

相关的脚本代码数量为:1

     

范围数:30

     

设定尺寸:1272

     

范围开始:41

     

范围结束:5a

     

范围开始:61

     

范围结束:7a

     

...

     

范围开始:ff41

     

范围结束:ff5a

这意味着所有字符范围与拉丁语区块相对应。

答案 1 :(得分:0)

虽然UTF映射中的某些部分专门针对某些语言,但并不完全清楚您的意思 - 例如正如你对希腊语所说的那样 - 有许多语言可以将这些字符分成许多不同的区域 - 例如许多欧洲语言使用ASCII字母 - A-Z等 - 并且还从160-240区域中的“扩展Latin1”中选择了字符。

所以任何“迭代”的工具都说Rumanian必须首先决定哪些字符是罗马尼亚语,然后用UTF识别它们,然后打印出来。

如果你不是那个意思,而是想从UTF打印出特定的分组,我建议你考虑使用UTF32作为你的基本编码,其中打印字符会更容易。

答案 2 :(得分:0)

语言块在unicode are listed here中的位置列表,因此您可以将字符的大部分字符拆分为自己的文件。

您需要列出每个呈现的字体文件中可用的字符,然后为每个呈现的字符串中的字符加载相应的字体文件。

但是 - 动态执行此操作可能不是一个好主意,因为它可能很慢(检查每个字符)以及当字符滑入时不会出现任何字符集时容易出现故障。

你可能会更好地反过来做;当有人初始化您的引擎时,它们会列出您应加载的语言块,并加载相应的文件。然后,当您渲染字符串时,只需删除当前不可用的任何字符。

答案 3 :(得分:0)

语言中实际使用的字符可以在exemplar sets中定义的CLDR中找到。

我不会构建复杂的UnicodeSet,而是迭代u+0000…u+10fff并测试uscript_getScript (UChar32 codepoint, UErrorCode *err)返回的脚本 - 对于示例代码,UnicodeSet将在内部执行相同的操作给出了答案。