首页 文章

是否可以使用ICU以任意编码从字符串中尾随空格/制表符,而无需进行任何转换

提问于
浏览
5

具体来说,给出以下内容:

  • 指向包含ICU支持的某些编码X中的字符串数据的缓冲区的指针

  • 缓冲区中数据的长度,以字节为单位

  • 缓冲区的编码(即X)

我可以计算字符串的长度,减去尾随空格/制表符,而不是先将其转换为ICU的内部编码,然后再转换回来吗? (由于unicode规范化,这本身可能会有问题) .

对于某些编码,例如任何基于ascii的编码以及utf-8/16/32,解决方案非常简单,只需从字符串的后面迭代,一次比较两个常量的1/2/4字节 .

对于其他人来说,它可能更难(可变长度编码浮现在脑海中) . 我希望这个尽可能高效 .

3 回答

  • 0

    对于大量的编码子集,以及 U+0020 SPACEHORIZONTAL TAB U+0009 的有限集合,这非常简单 .

    在ASCII,单字节Windows代码页和单字节ISO代码页中,这些字符都具有相同的值 . 只要值为9或32,您就可以简单地逐个字节地向后工作,将它们关闭 .

    这种方法也适用于UTF-8,它具有很好的属性,即小于128的字节始终是ASCII字符 . 您不必怀疑它是前导字节还是连续字节,因为它们始终具有高位设置 .

    给定UTF-16,您一次工作两个字节,查找0x0009和0x0020,小心处理字节顺序 . 与UTF-8一样,UTF-16具有很好的属性,如果你看到这个值,你不必怀疑它是否是代理对的一部分,因为它们总是具有不同的值 .

    有问题的情况是可变字节编码,它们必须知道它是一个制表符还是来自多字节编码的随机字节 . 但是,即使对于其中一些,您关注的特定值(9和32)也许是唯一的 . 例如,查看Windows code page 950,似乎前导字节具有高值设置,并且尾部字节避开较低的值(需要大量检查才能绝对确定) . 因此,对于您的有限情况,这可能就足够了 .

    对于从绝对任何编码中剥离任意字符集的一般问题,您需要根据该编码的规则解析字符串(以及了解所有字符映射) . 对于一般情况,几乎可以肯定最好将字符串转换为某种Unicode编码,进行修剪,然后转换回来 . 如果您小心使用K标准化表格,这应该正确往返 .

  • 6

    我使用相当简单的STL方法:

    std::string mystring;
    mystring.erase(mystring.find_last_not_of(" \n\r\t")+1);
    

    到目前为止,这似乎适用于我的所有需求(你的里程可能会有所不同),但经过多年的使用它似乎做了工作:)

    如果您需要更多信息,请与我们联系:)

  • 1

    如果将“任意编码”要求限制为“使用与空格相同的代码值的任何编码和选项卡作为ascii”,这仍然相当普遍,您甚至根本不需要ICU . 你需要的是boost :: trim_right或boost :: trim_right_if .

    http://www.boost.org/doc/libs/1_55_0/doc/html/string_algo/usage.html#idp206822440

相关问题