创建角色名如何在中英文混排的情况下精确限制长度
2015-10-14 23:53
393 查看
文章不够精炼。我想把我的思想过程写出来,一遍以后自己读的时候知道我当时的想法。写的时候也尽量精简了一些不必要的话。
如果有什么问题的话,希望看到的各位不吝赐教。
公司用cocos2dx做游戏,使用语言是lua。
最近做角色创建。要求最多英文14个,中文7个,超过的就不能输入。(不知道什么时候起我记忆中英文是一个字节的,而中文是两个字节的。这也是比较普遍的想法吧。)
开始尝试了一下cocos2dx自带的EditBox控件的setMaxLength方法。
效果不好,发现cocos2dx把任何语言都当成一个字节去计算。也就是中文可以输入14个它才会去限制。
只能通过editbox的事件来重新计算长度了。
尝试了一下lua的string.len方法返回的长度是什么。发现一个中文返回的长度是3。有点傻眼。马上去百度了一下utf8的中文。发现回答都是
大部分的图形语言都是3个字节组成的。这颠覆了我以前的记忆……
经过了曲折的思想,这中间尝试了很多方法(比如计算出所有英文的总数,然后把剩下的字节除以3,得到剩下中文个数,这显然不可行,一不能确定所有的中文都是3个字节,就算都是3个字节,那要是输入其他文字呢?要知道utf8最多是6个字节的。)发现都无法如意,没办法,继续查找百度看有没有解决方法。
终于找到这篇文章:lua中截取UTF8字符串的方法(无乱码)
其中有一段
if dropping >= 128 and dropping < 192 then 这里的话,UTF8是多字符集,但是第一个字符的最高位是11XXXXXX,其他的字符最高位是10XXXXXX
这里就应该很清楚的说明了utf8中,最高位是以11XXXXXX开头的。所以可以计算出它在这一位的最小数是192(11000000)。也就是说utf8最高位的最小值是192.(非英文)
在这里我不放心,因为该博主只说了事实没有其他说明,我不能确定他说的是否是正确的,是否具有普遍性,而不仅仅是中文。所以又开始查utf8的规范。
在这篇博文中我们可以看到utf8的构成:
UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000-7FFF FFFF 1111110x 10xxxxxx … 10xxxxxx
其他不管。是否发现从2字节开始所有的组成都是以11开头的?
现在没有顾虑了。既然除了1字节的文字外,所有的2字节以上的文字的最高位的最小值是192,那么我们可以通过
每个最高位是否不小于192来计算文字的长度:
下面代码只验证了中文是可行的,未验证其他语言,如果有问题的话,请予以指正。谢谢。
如果有什么问题的话,希望看到的各位不吝赐教。
公司用cocos2dx做游戏,使用语言是lua。
最近做角色创建。要求最多英文14个,中文7个,超过的就不能输入。(不知道什么时候起我记忆中英文是一个字节的,而中文是两个字节的。这也是比较普遍的想法吧。)
开始尝试了一下cocos2dx自带的EditBox控件的setMaxLength方法。
local editBox = ccui.EditBox:create(cc.size(inputBgSize.width - 30,inputBgSize.height - 16),"pop_input_text.png") editBox:setMaxLength(14)
效果不好,发现cocos2dx把任何语言都当成一个字节去计算。也就是中文可以输入14个它才会去限制。
只能通过editbox的事件来重新计算长度了。
尝试了一下lua的string.len方法返回的长度是什么。发现一个中文返回的长度是3。有点傻眼。马上去百度了一下utf8的中文。发现回答都是
大部分的图形语言都是3个字节组成的。这颠覆了我以前的记忆……
经过了曲折的思想,这中间尝试了很多方法(比如计算出所有英文的总数,然后把剩下的字节除以3,得到剩下中文个数,这显然不可行,一不能确定所有的中文都是3个字节,就算都是3个字节,那要是输入其他文字呢?要知道utf8最多是6个字节的。)发现都无法如意,没办法,继续查找百度看有没有解决方法。
终于找到这篇文章:lua中截取UTF8字符串的方法(无乱码)
其中有一段
if dropping >= 128 and dropping < 192 then 这里的话,UTF8是多字符集,但是第一个字符的最高位是11XXXXXX,其他的字符最高位是10XXXXXX
这里就应该很清楚的说明了utf8中,最高位是以11XXXXXX开头的。所以可以计算出它在这一位的最小数是192(11000000)。也就是说utf8最高位的最小值是192.(非英文)
在这里我不放心,因为该博主只说了事实没有其他说明,我不能确定他说的是否是正确的,是否具有普遍性,而不仅仅是中文。所以又开始查utf8的规范。
在这篇博文中我们可以看到utf8的构成:
UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000-7FFF FFFF 1111110x 10xxxxxx … 10xxxxxx
其他不管。是否发现从2字节开始所有的组成都是以11开头的?
现在没有顾虑了。既然除了1字节的文字外,所有的2字节以上的文字的最高位的最小值是192,那么我们可以通过
每个最高位是否不小于192来计算文字的长度:
下面代码只验证了中文是可行的,未验证其他语言,如果有问题的话,请予以指正。谢谢。
if eventType == "began" then -- triggered when an edit box gains focus after keyboard is shown elseif eventType == "ended" then -- triggered when an edit box loses focus after keyboard is hidden. elseif eventType == "changed" then local str = editBox:getText() str = string.gsub(str," ","")--过滤掉空格 local count = string.len(str) local reCount = 0 local beginIndex = -1 local reString = "" for i = 1, count do local s = string.sub(str, i, i) local t = string.byte(s) if t < 128 then reCount = reCount + 1--1字节文字,长度加1 elseif t >= 192 then reCount = reCount + 2--1字节以上文字,长度加2 end if reCount > CharacterLayer.nameMaxLength then beginIndex = i - 1 break end beginIndex = i end reString = string.sub(str, 1, beginIndex) editBox:setText(reString) elseif eventType == "return" then -- triggered when the return button was pressed or the outside area of keyboard was touched. end
相关文章推荐
- C++11新特性之std::function
- <hx>标签,为你的网页添加标题
- 解析包时出现错误,用代码安装apk出现问题
- 22.Oracle数据库SQL开发之 SQL92语法执行连接
- JavaScript语法
- Thread、Handler与HandlerThread
- OC与Swift混编
- PHP方法之 substr
- 21.Oracle数据库SQL开发之 连接条件和链接类型
- 古堡算式
- POJ 3259 SPFA
- django 静态资源配置详解
- QT窗体背景色设置
- php session_start()关于Cannot send session cache limiter - headers already sent 错误解决方法
- linux命令行中光标(非vim光标)移动技巧------提升开发效率
- Winsocket UDP Client and Server Examples
- [Django模板系统]方法调用与无效变量处理
- CentOS源码安装搭建LNMP全过程(包括nginx,mysql,php,svn)
- <p>标签
- [转]Android应用中返回键的监听及处理