具体来说,给出以下内容:
-
指向包含ICU支持的某些编码X中的字符串数据的缓冲区的指针
-
缓冲区中数据的长度,以字节为单位
-
缓冲区的编码(即X)
我可以计算字符串的长度,减去尾随空格/制表符,而不是先将其转换为ICU的内部编码,然后再转换回来吗? (由于unicode规范化,这本身可能会有问题) .
对于某些编码,例如任何基于ascii的编码以及utf-8/16/32,解决方案非常简单,只需从字符串的后面迭代,一次比较两个常量的1/2/4字节 .
对于其他人来说,它可能更难(可变长度编码浮现在脑海中) . 我希望这个尽可能高效 .
3 回答
对于大量的编码子集,以及
U+0020 SPACE
和HORIZONTAL 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标准化表格,这应该正确往返 .
我使用相当简单的STL方法:
到目前为止,这似乎适用于我的所有需求(你的里程可能会有所不同),但经过多年的使用它似乎做了工作:)
如果您需要更多信息,请与我们联系:)
如果将“任意编码”要求限制为“使用与空格相同的代码值的任何编码和选项卡作为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