通过utf8多字节字符串向后迭代

时间:2014-03-07 18:05:31

标签: c string utf-8 iteration

我使用此函数is_utf8 https://stackoverflow.com/a/1031773/275677的略微修改版本从字符数组中提取UTF8序列,返回序列及其中的字节数,以便我可以在此处迭代字符串方式。

但是我现在想要在字符串(char *)上向后迭代。这样做的最佳方式是什么?


我的猜测是尝试将字符串的最后四个,三个,两个和一个字节分类为utf8(四次)并选择最长的。

然而,utf8是否具有暧昧的情况?例如,解析为aaaabb的{​​{1}}也可以aaaa.bb解析(向后)aa.aabbaaaaaa和{{1}是有效的utf8序列?

2 个答案:

答案 0 :(得分:12)

字符串由一系列UTF-8序列组成。所有UTF-8序列:

  • EITHER 只包含一个八位字节(你和我的字节),顶部位清除

  • OR 由一个八位字节组成,其中两个最高位设置,后跟一个或多个八位字节,第7位设置,第6位清除。

有关详细信息,请参阅http://en.wikipedia.org/wiki/Utf8#Description

所以你需要做的是检查相关字符是否有第7位设置和第6位清除,如果是这样,请退一步,注意不要超出字符串的开头(请注意,如果字符串是形成良好,这不会发生。)

未经测试的C-ish伪代码:

char *
findPrevious (const char *ptr, const char *start)
{
    do
    {
        if (ptr <= start)
            return NULL; /* we're already at the start of the string */
        ptr--;
    } while ((*ptr & 0xC0) == 0x80);
    return ptr;
} 

答案 1 :(得分:0)

这看起来很有帮助。从内存的深度我回忆说,你可以通过峰值来判断每个字节的前一个或两个位 - 这使得查看字符串的长度变得微不足道,然后使用原始函数来验证它。

  

UTF-8字符是单个字节,其中最左边的位是0或多个字节,其中第一个字节最左边的位是1..10 ...(左边的数字为1) 2或更多)后跟表格10的连续字节...(即左边的单个1)。假设你的字符串格式正确,你可以循环遍历所有字节并在每次看到一个不是10的形式的字节时递增你的“字符数”... - 即只计算所有UTF-8中的第一个字节字符。

https://stackoverflow.com/a/7108478/275677

也是http://en.wikipedia.org/wiki/UTF-8#Description

的表格