1

我想遍历 Unicode 字符,吞噬所有遵循初始代码点的组合字符。

到目前为止,这是我所拥有的,但是对于我尝试过的一些随机 Unicode 序列,它的行为真的很奇怪:(例如,当我传递它时,像“a̔”(U+0061 LATIN SMALL LETTER A 后跟 U+0314 COMBINING REVERSED COMMA ABOVE) 将其视为两个字符而不是一个字符。其他内容,如“e︠”(U+0065 拉丁小写字母 E 后跟 U+FE20 组合连字左半边)被视为一个字符)

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;
}
4

1 回答 1

3

实际上,Unicode 字符大多是 1:1 到 Unicode 代码点 - 你感兴趣的是 Unicode 字素簇,它对应于所谓的用户感知字符。

您可以在 bitbucket找到我的算法实现,包括属性数据

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

gc_break_property(c) == GC_BP_Extend

检查具有属性Grapheme_Extend的字符和

gc_break_property(c) & GC_FLAG_POSTFIX

如果您还想包含间距标记。

于 2012-04-30T13:11:41.197 回答