开发者社区> 问答> 正文

ThinkSNS 如何计算字符显示长度

  今天我们来聊一下可能很多人都会头疼的东西:显示长度。


  需求是这样的,在字符的显示上,两个英文单词才占一个中文或者其他语言的显示长度。如下:


  


  上面排的是两个英文字母,一个汉字,一个Emoji。你会发现,在显示上占的宽度是一致的。一些设计上为了好看也要求有这样的处理。


  例如,我们的用户名需求是最多12个非单字节字符或者24个单字节字符的需求也可以混合排的需求,我们写后端不得不处理这样的验证了。


  需求规则是/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/


  在ThinkSNS+中,为了能把这部分验证公用,所以选择使用自定义验证规则。我们先说下计算的实现思路吧!


  首先,就算是mb_strlen也没法准确的获取多字节字符和单子节字符混合在一起的长度,网上有个说法,汉字占三个字节,英文数组半角符号占一个字节,所以:


 


  用这个方法可以得到单字节占0.5多字节占1的计算。但是以中文为例,只有两万个汉字才是这种情况,还有六万多汉字是四个,其次,emoji也是四个字节。根本无法准确的计算。


  好在在无意间发现一个奇怪的东西str_word_count这个函数计算非英文单词外是除了符号例如中文就是按照汉字个数算的,emoji也是同理。


  发现这个以后,咱们就好办了。我们吧用户名中的[a-aA-Z0-9_]剔除掉,单独计算不就是我们要的验证长度了吗?


  所以,首先我们用:


  


  方式单独计算出单字节字符的显示长度,再用:


  


  方式计算出多字节的长度,最后:


  


  就得出了显示长度,实现了,最后封装成验证规则:


    


  代码是原型代码,还没有进行优化,之后我们只要按照下面的方式用:


  


  现在就很好的解决了这个需求。


  我们很乐意,将基于Laravel的ThinkSNS+产品开发中的技术解决方案分享给大家,也希望喜欢的朋友能给国内开源产品一点点的支持。

展开
收起
ThinkSNS 2017-09-27 14:57:40 3577 0
0 条回答
写回答
取消 提交回答
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载