如何迭代Unicode字符? (不是代码点)

时间:2012-04-30 12:10:57

标签: c unicode utf-8

我想迭代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;
}

1 个答案:

答案 0 :(得分:3)

实际上,Unicode字符大多是1:1到Unicode代码点 - 您感兴趣的是Unicode字形集群,它们对应于所谓的用户感知字符。

您可以找到the algorithm的实施内容,包括property datahere at bitbucket

如果您对完整算法不感兴趣,可以使用

gc_break_property(c) == GC_BP_Extend

检查属性 Grapheme_Extend

的字符
gc_break_property(c) & GC_FLAG_POSTFIX

如果你想包括间距标记。