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