用过Lua的,应该知道lua有一个截取字符串的接口,string.sub(s,i,j),就是截取字符串s,从第i个字符到第j个字符的字串,这里的一个字符是一个字节,对于英文字母还是阿拉伯数学,不管是utf8编码,还是ansi(GBK)编码,都是一样的,而且对于汉字,前者占3个字节,后者占2个字节,当然还有4个字节的汉字,那如何从一个字符串比如"bg%好-+03打@/f"中准确截取出我们需要的汉字呢,这就是我们今天需要解决的问题.
其实,在今天之前,我也不知道怎么做,我是因为要解决一个模糊查找的需求来学习到了这些
首先当前游戏代码是以utf8编码格式,因为我们要面向中国玩家,而且很多英语不是非常好,哈哈,所以全写英文的,玩家就看不懂了,如果ui显示文字全是英文,下面的就不需要看了
1.字符是由几个字节组成:(16进制)
[0, 0xc0) 表示这个字符仅由1个字节构成 [0,192)
[0xc0, 0xe0) 表示这个字符由2个字节构成 [192,225)
[0xe0, 0xf0) 表示这个字符由3个字节构成 [225,240)
[0xf0, 0xff) 表示这个字符由4个字节构成 [240,255)
2.如何取得字节ASCII码 :
string.byte(s,i) 或 s:byte(i)
3.我们先写一个判断utf8字符byte长度的函数:
4.在Lua中,表(table)是十分重要的一种数据结构,实际上Lua对于复杂数据类型也仅提供了表给我们,我们通过表可以实现我们需要的大部分重要的数据结构,比如数组。我们现在只需要知道有没有相同的中文字符,其他不关心,所以把字符串变成数据中文字符串的表就好了
我们传入两个参数,一个是字符串,一个是用来装汉字的表
通常来说,汉字范围从0x4E00到0x9FA5,转换为UTF-8编码为11100100 10111000 10000000(228, 184, 128) 到 11101001 10111110 10100101(233, 190, 165)
因此,中文UTF-8编码用3个字节表示,要遵守格式:1110xxxx 10xxxxxx 10xxxxxx
即第一个字节的取值区间为 [11100000, 11110000) = [0xe0, 0xf0) = [224, 240) 左开右闭
后两个字节的取值区间为[10000000, 10111111] = [0x80,0xbf] = [128, 191] 开区间
所以我们可以一个字节的去截取,然后计算出byte长度,如果大于3,就截取存入表中
5.写好算法以后,我们只需传入不同的字符串,得到不同的表,进行比较就可以了:
我们只比较两个字符串都含有中文的情况