我想迭代Unicode字符,吞噬所有符合初始代码点的字符。
这就是我到目前为止所做的,但是对于我尝试过的一些随机Unicode序列,它的行为非常奇怪:(例如,当我传递“a̔”之类的东西时(U + 0061 LATIN SMALL LETTER A后跟U + 0314)结合反转的COMMA上面)它把它看作两个字符而不是一个。其他的东西,比如“e +”(U + 0065 LATIN SMALL LETTER E,其次是U + FE20 COMLINING LIGATURE LEFT HALF)被视为一个字符)
int COMBINING[] = {
0x0300, 0x036F,
0x1DC0, 0x1DFF,
0x20D0, 0x20FF,
0xFE20, 0xFE2F,
0 //sentinel
};
utf8_index_t ut_nextchar(utf8_t source, utf8_index_t curr)
{
int c = decode_cp(source, &curr);
int comb = 0;
if (c == 0)
return -1;
while (COMBINING[comb] != 0)
{
for (comb = 0; COMBINING[comb] != 0; comb += 2)
{
if (c >= COMBINING[comb] && c <= COMBINING[comb + 1])
{
c = decode_cp(source, &curr);
if (c == 0)
return -1;
break;
}
}
}
return curr;
}
答案 0 :(得分:3)
实际上,Unicode字符大多是1:1到Unicode代码点 - 您感兴趣的是Unicode字形集群,它们对应于所谓的用户感知字符。
您可以找到the algorithm的实施内容,包括property data,here at bitbucket。
如果您对完整算法不感兴趣,可以使用
gc_break_property(c) == GC_BP_Extend
检查属性 Grapheme_Extend 和
的字符gc_break_property(c) & GC_FLAG_POSTFIX
如果你想包括间距标记。