javascriptのリアルゲーム投稿サイト -sightlasの開発ブログ

sightlasの開発ブログと称して、全然関係のない(?)技術論や日常の出来事を書きます。

JavaScriptで個別に扱えない文字

テスト中にJavaScriptでうまく扱えない文字が出てきた。

 

JavaScript実行時の文字列の処理は、内部ではUTF-16で扱っているらしい。

UTF-16というのは可変長マルチバイト。ある文字のデータ長が可変長ということ。どの文字がどれぐらいのデータ長か、ひとつひとつ見ないとわからない、ということでもある。

これが問題になるのが、例えば、3番目の文字を取得する、というコードを書いたとき。

本来なら文字列の前から順番に調べていかないと、3番目の文字が、文字列データの中でどこにあるのかわからない(可変長なので)

だけどJavaScriptはエイヤ!で、その文字の位置を取得してくるので、レアな漢字がデータに存在すると、位置や長さの取得値がずれてしまう。

以下テスト内容と結果です。

 

テストコード:

//叱じゃなくて𠮟だよ!叱𠮟。どこに違いがあるかわからないけど!
console.log("超 .charCodeAt:%d .length:%d", "超".charCodeAt(0), "超".length);
console.log("𠮟 .charCodeAt:%d .length:%d", "𠮟".charCodeAt(0), "𠮟".length);
console.log("0𠮟123".charAt(0));
console.log("0𠮟123".charAt(1));
console.log("0𠮟123".charAt(2));
console.log("0𠮟123".charAt(3));
console.log("0𠮟123".charAt(4));

 

 

結果: 

「超」という漢字は一文字(length=1)なのに、「𠮟」は2文字とカウントされる。

また、「𠮟」や、その後ろの文字を抽出しようとすると文字化けを起こす。

 

chrome:49.0

f:id:sightlas:20160502132222p:plain

 

Internet explore:11.0

f:id:sightlas:20160502132313p:plain

 

firefox:45.0

f:id:sightlas:20160502132324p:plain

 

ブラウザ間で動作が一緒なので、JavaScriptの仕様らしい。

ということは、これが原因で文字数カウントをミスったり、エラーとなった時は、、、、「複雑な漢字は使えません」でお茶を濁そう!

 

人の名前に複雑な漢字が含まれる場合などは、 こちらの正規表現を使った解決策でいけそうですね。

 

teppeis.hatenablog.com