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+ 產品開發中的技術解決方案分享給大家,也希望喜歡的朋友能給國內開源產品一點點的支持。
開源代碼倉庫:
GitHub:https://github.com/zhiyicx/thinksns-plus(點擊star,每日關注開發動態。)
官網:https://www.thinksns.com/
最後更新:2017-09-28 15:03:26