一個emoji文本用javascript該如何正確計算其文本長度?
最容易想到的天然是用length
來求長度。如下列舉常見emoji和複雜emoji。javascript
// size: 2 "?".length // size: 7 "???".length
因爲JavaScript的字符編碼問題,天然行不通。詳情請參見文章末尾的博文。
基於常見的emoji可使用如下正則匹配。html
// 匹配UTF-16的代理對,把代理對改成一個BMP的字符 function countSymbols(string) { var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; return string.replace(regexAstralSymbols, '_').length; } countSymbols("?"); // size: 1 countSymbols("???"); // size: 4
可是仍然出現了問題。那麼一些更復雜的emoji表情的時候,仍是掛掉了。???
這個表情實際上是蘋果中表情農民,在Full Emoji List, v5.0裏第218個表情。此表情由U+1F468 U+1F3FC U+200D U+1F33E
組成。因此直接求長度爲 2 + 2 + 1 + 2 = 7。這也在所不免了。java
那麼該作如何解?git
這時候社區裏有twitter的關於emoji的一個工具庫twemoji,利用這個工具庫,能夠方便的實現emoji文本的實現。github
twemoji.parse("???") // "<img class="emoji" draggable="false" alt="???" src="https://twemoji.maxcdn.com/2/72x72/1f468-1f3fc-200d-1f33e.png"/>"
所以可見。twemoji正確的識別了並達到了咱們的預期。用戶任意輸入一個emoji,咱們都只計算爲一個長度。利用twemoji解析emoji並返回圖片的特性,結合正則能夠實現一個函數。web
function countSymbols(string) { return twemoji.parse(string).replace(/<img.+?\/>/g, '_').length; } countSymbols("?"); // size: 1 countSymbols("???"); // size: 1
好的問題解決了。結合twemoji和簡單的正則就能夠實現一個文本計算函數函數
countSymbols("??? and ? parse correctly!"); // size: 24
其實當字符計算解決後,輸入框限制字符數就垂手可得了。思路就是每次input事件發生時,先判斷當前字符數是否超過限制,若是超出,則用上一次的文本替換當前輸入框的文本。大體代碼以下。工具
var prevText = ''; var textarea = document.getElementById('input-area'); var limit = 250; function limitTextSize(){ var text = textarea.value; var size = countSymbols(text); if(size > limit) { textarea.value = prevText; } else { prevText = text; } }
但願能給你們帶來點幫助。求點贊哈哈~編碼
Unicode與JavaScript詳解
Emoji.prototype.length —— Unicode 字符那些事兒
JavaScript 有個 Unicode 的天坑prototype