开发者社区 问答 正文

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 3599 分享 版权
阿里云 AI 助理回答

从你的描述中,可以看出你正在处理一个多语言环境下字符显示长度统一的问题,尤其是在Web开发中,确保不同字符(如英文、中文、Emoji等)在界面上占用相同宽度的显示需求。你提到了使用ThinkSNS框架,并通过自定义验证规则来实现这一需求。

解决方案回顾

  1. 问题识别:需要一个机制来准确计算混合了多字节字符(如中文、Emoji)和单字节字符(如英文、数字)的字符串在视觉上的“长度”,以满足特定的设计要求。

  2. 初步尝试:最初尝试使用mb_strlen函数,但发现它不能直接解决多字节与单字节混合字符串的精确长度计算问题,因为不同的字符可能占用不同的字节数。

  3. 解决方案

    • 利用str_word_count函数的一个特性,该函数在计算非英文单词时,对于中文字符和Emoji等特殊字符,能够按照实际的视觉“单位”计数,这为解决问题提供了思路。
    • 通过正则表达式剔除用户名中的单字节字符([a-zA-Z0-9_]),单独计算剩下的多字节字符数量,以此作为多字节部分的长度。
    • 最后,结合单字节字符的数量,根据每个单字节字符视作0.5个视觉单位,计算出总显示长度。
  4. 代码实现

    • 使用正则表达式preg_replace('/[a-zA-Z0-9_]/', '', $username)移除所有单字节字符,然后用str_word_count($result, 0)计算剩余字符数量作为多字节字符的视觉长度。
    • 单字节字符数量直接统计,然后乘以0.5得到其视觉长度。
    • 将两者相加即得最终的显示长度。
  5. 封装验证规则:将上述逻辑封装成自定义验证规则,以便在ThinkSNS或其他基于Laravel的项目中复用。

进一步优化建议

  • 性能考虑:虽然当前方案实现了功能,但在处理大量数据或高并发场景下,频繁的正则替换和多次函数调用可能会对性能产生影响。可以考虑一次性遍历字符串,同时统计单字节和多字节字符数量,减少函数调用次数。
  • 国际化支持:考虑到全球化应用,未来可能需要更精细地处理其他语言的字符编码差异,比如某些语言的特殊字符可能也需要特别处理。
  • 利用现有库或工具:检查是否有现成的PHP库或框架内置功能能更高效、准确地处理这类问题,比如一些专为多语言文本处理设计的库。

分享这些技术细节和解决方案不仅有助于提升开发者在处理类似问题时的效率,也促进了开源社区的知识交流和进步。希望ThinkSNS团队能继续贡献更多有价值的解决方案,推动国内开源产品的发展。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: