社交系统 ThinkSNS+ 是如何计算字符显示长度的? [研发日记五]

2017-05-27 16:15:12 +08:00
 Zhiyicx

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

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

上面排的是两个英文字母,一个汉字,一个 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+基于  Laravel master  分支 [研发日记一] 》

《 ThinkSNS+研发中前端的抉择( webpack/Vue )踩坑日记 [研发日记二] 》

《基于 Laravel Route 的 ThinkSNS+ Component [研发日记三] 》

《如何做到  Laravel 配置可以网站后台配置 [研发日记四] 》

开源代码仓库:

GitHub:https://github.com/zhiyicx/thinksns-plus(点击 star,每日关注开发动态。)

咨询 QQ:3298713109

官网:http://www.thinksns.com/

内测申请方式

提供个人 /企业联系方式及认证信息(真实姓名 /企业营业执照照片或扫描件)及申请说明,发送邮件至 lihecong@zhishisoft.com 将有机会获得首批内测资格,名额有限,申请从速。

参与内测请提供以下资料

1 个可接收验证码的手机号; 1 个指定邮箱; 1 位测试人员姓名; 1 个您喜欢的账号昵称

开源不易,为了争取开源,我们团队做了很多努力。把基于 Laravel 的作品展示在大家面前,之后专栏会持续不断的分享 ThinkSNS +开发过程中的技术细节。

2225 次点击
所在节点    程序员
2 条回复
oott123
2017-05-27 21:43:17 +08:00
hainuo
2017-05-28 07:05:52 +08:00
其实一个 mb_strlen 指定字符集 就好了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/364260

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX