繁体   English   中英

遍历utf-8中的字符块

[英]iterate over characters blocks in utf-8

我的任务是遍历与给定语言(区域设置)相对应的所有utf-8字符代码。 我想这不是那么容易,我必须遍历字符块(例如,对于“ ru_RU”来说,整个西里尔字母)。 我可以在Wiki页面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字体保留在内存中始终,但仅在检测到语言环境后才加载相应的文件。

谢谢!

因此,我已通过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

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

您的意思还不清楚,尽管UTF映射中有专门针对某些语言的部分-例如您所说的希腊语-许多语言中的字符被划分为多个不同区域-例如,许多欧洲语言使用ASCII字母-AZ等-以及从160-240区域中设置的“扩展Latin1”中选择的字符。

因此,任何要“反复说”罗马尼亚语的工具都必须首先确定罗马尼亚语的字符,然后以UTF标识它们,然后打印出来。

如果您不是全部意思,而是想从UTF打印出特定的分组,我建议您考虑使用UTF32作为基本编码,这样打印字符会容易得多。

此处列出了unicode中语言块的位置列表 ,因此您可以将大多数字符拆分成自己的文件。

您需要列出每个渲染的字体文件中可用的字符,然后为渲染的每个字符串中的字符加载适当的字体文件。

但是,动态地执行此操作可能不是一个好主意,因为它可能很慢(检查每个字符),并且在没有任何字符集的字符插入时容易失败。

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

语言中实际使用的字符可以在CLDR中定义的示例集中找到。

除了构建复杂的UnicodeSet之外,我只需要遍历u+0000…u+10fff并测试uscript_getScript (UChar32 codepoint, UErrorCode *err)返回的脚本uscript_getScript (UChar32 codepoint, UErrorCode *err) -UnicodeSet在内部将对此进行相同的处理。您提供的示例代码作为答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM