[分享] Javascript 計算字元長度, count string length by javascript

今天遇到一個問題,很簡單的一個問題當有一個input box需要限制輸入長度,想當然很簡單在input 裡面加上一個maxlength屬性就可以完成限制,接著有另一個更大的問題,因為使用者從多個國家而來,我們需要接受,『中英輸入』的文字,那問題就出現了!

像是Facebook album就有這樣的問題存在,當我很開心的輸入了一連串的國,直到不能輸入為止,再按下儲存,本以為『國國國國國….國國國』相簿應該會存在,可惜…

[![](http://3.bp.blogspot.com/-2oyHbZOz9f4/Th8o-BIRS4I/AAAAAAAAMvk/6jJWVkresrQ/s1600/2011-07-15_013422.jpg)](http://3.bp.blogspot.com/-2oyHbZOz9f4/Th8o-BIRS4I/AAAAAAAAMvk/6jJWVkresrQ/s1600/2011-07-15_013422.jpg)
[![](http://3.bp.blogspot.com/-r7Q8mhbsUtI/Th8pSIw3XAI/AAAAAAAAMvo/nV7Mkt8jhE8/s1600/2011-07-15_013525.jpg)](http://3.bp.blogspot.com/-r7Q8mhbsUtI/Th8pSIw3XAI/AAAAAAAAMvo/nV7Mkt8jhE8/s1600/2011-07-15_013525.jpg)
實際上後面卻給我出現外星符號,而且我剛剛輸入的『國國國….』應該是目前數量2倍之多啊,為什麼會這樣子,搞了許久發現問題在於,在PHP認定字串長度是使用byte來計算,並不是採用字元為單位。 前端頁面的算法,input box裡面,一個字為一個長度,在Javascript裡面也是,一個字就是一個長度,所以前端所看到的字串,丟到PHP之後又變成了第三度空間,內容都會被扭曲,尤其是尾巴的部份。 **介紹將字串轉換為Byte 計算長度:** `"測試".length;

// output : 2;



"ab".length;

// output : 2;

` 這樣子的結果似乎不是我們要得,所以我們決定轉換另一個方向,將所有字元長度都先轉換為byte code,之後再計算字元長度。 `encodeURIComponent("測試");

// output "%E6%B8%AC%E8%A9%A6"



encodeURIComponent("ab");

// output "ab"

` 轉換成 byte之後,感覺上就可以開始計算了,**一個中文可以切成3個byte,1個byte會呈現%dd**,就可以計算成一個中文字,將上面得到的字串長度再除**3**就可以得知目前字長度。 `var str = encodeURIComponent("測試");

console.log(str.length /3);

// output 6

` 乍看之下的確如此,但是**中英文**的情況會是如何!? 剛剛的結果很明顯長度為**6**,如果在中間穿插3個英文,會是什麼狀況? `var str = encodeURIComponent("a測b試c");

console.log(str.length /3);

// output: 7

// expect output: 6 + 3

` 實際輸出結果會是**7**,不,這並不是我們想要的答案。既然知道byte code結構為**%dd**,那我們就使用[正規表示法](http://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F),將需要的字元做取代,這樣所取得的字串長度就是實際需要的長度了。 `replace(/%[A-Fd]{2}/g, 'U')

` 接著拿剛才的實際狀況來測試,沒錯真的是我們所需要的結果,太好啦,大功告成。 `var str = encodeURIComponent("測試");

str = str.replace(/%[A-Fd]{2}/g, 'U').length;

console.log(str);

// output: 6



var str = encodeURIComponent("a測b試c");

str = str.replace(/%[A-Fd]{2}/g, 'U').length;

console.log(str);

// output: 9

` **後記:** [正規表示法](http://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F)果然夠威,夠強大,令所有文字都能夠臣服於它的腳下,實在是感受到無限的威力。這次也要感謝同事的協助才能順利找到這個答案,果然在大家身上都可以學到很多很多,所以別輕易相信**input maxlength這個屬性**,**有時候眼前所看到的不一定為真,還是要實際測試過後才會清楚得到答案。** ** ** 全文資料參考[Count bytes in textarea using javascript](http://stackoverflow.com/questions/2848462/count-bytes-in-textarea-using-javascript)
**[工商服務]**
[NodeJS Taiwan](http://www.facebook.com/NodeJS.tw)期待更多人的支持,希望能夠聽到你的回應及分享。

CaesarChi

Web developer, focus on website fullstack, special JavaScript, and love sharing developing experience and communicate with developers. http://about.me/clonn