我正在解析一些UTF-8文本,但我只对ASCII范围内的字符感兴趣,即我可以跳过多字节序列.
我可以很容易地检测到序列的开始,因为符号位已设置,因此char值<0.但是如何判断序列中有多少字节,以便我可以跳过它?
我不需要执行任何验证,即,我可以假设输入是有效的UTF-8.
尽管Deduplicator的答案更适合跳过多字节序列的特定目的,但如果需要获取每个这样的字符的长度,则将第一个字节传递给此函数:
int getUTF8SequenceLength (unsigned char firstPoint) {
firstPoint >>= 4;
firstPoint &= 7;
if (firstPoint == 4) return 2;
return firstPoint - 3;
}
Run Code Online (Sandbox Code Playgroud)
这将返回序列的总长度,包括第一个字节.firstPoint为了清楚起见,我在这里使用了unsigned char值作为参数,但请注意,如果参数是signed char,则此函数的工作方式完全相同.
解释:
UTF-8使用序列的第一个字节中的第5,6和7位来指示剩余长度.如果全部三个都设置,则序列是3个额外字节.如果仅设置左起第一个(第7位),则序列为1个附加字节.如果设置了左边的前两个,则序列是另外2个字节.因此,我们想要检查这三个位(这里的值只是一个例子):
11110111
^^^
Run Code Online (Sandbox Code Playgroud)该值向下移动4,然后向下移动7.这样只留下右边的第1,第2和第3位作为唯一可能的位.这些位的值分别为1,2和4.
00000111
^^^
Run Code Online (Sandbox Code Playgroud)如果该值现在为4,我们只知道左侧的第一位(我们正在考虑的三位)已设置并且可以返回2.
在此之后,该值为7,表示所有三个位都已设置,因此序列总共为4个字节,或者为6,表示左侧的前两个值已设置,因此序列总共为3个字节.
这涵盖了以UTF-8表示的有效Unicode字符的范围.
只需删除所有无效的字节ascii,不要试图变得可爱并且完全解释字节> 127.只要您在ascii范围内没有任何带基本字符的组合序列,这就可以工作.对于那些你需要解释代码点本身.