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
Internet explore:11.0
firefox:45.0
ブラウザ間で動作が一緒なので、JavaScriptの仕様らしい。
ということは、これが原因で文字数カウントをミスったり、エラーとなった時は、、、、「複雑な漢字は使えません」でお茶を濁そう!
人の名前に複雑な漢字が含まれる場合などは、 こちらの正規表現を使った解決策でいけそうですね。