[JavaScript General] JavaScript でサロゲートペアを考慮して文字数をカウントする
http://codepen.io/ 上で悩んだのでまとめておく。
[markdown]
> * [JavaScript Stringでサロゲートペアを扱う – teppeis blog](http://teppeis.hatenablog.com/entry/2014/01/surrogate-pair-in-javascript)
> * [Firefox 27(Nightly) における新たな String.prototype[”@@iterator”] – hogehoge @teramako](http://d.hatena.ne.jp/teramako/20131024/p1)
ES5 ではこんな感じで。
“`javascript
const str = ‘𠮷野家で𩸽’;
function strlenEs5(str) {
return str.length – (str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || []).length;
}
console.log(‘ES5’, strlenEs5(str)); // 5
“`
ES2015 Spread Operator を使うと短く書けるということだが、うまく数えないし書き直せない。
“`javascript
const str = ‘𠮷野家で𩸽’;
console.log(‘length’, str.length); // 7
console.log(‘count’, […str].length); // 1
“`
文字を配列として受け取り扱うという事かなぁ。
ということでそれっぽいコードを書いてみた。
“`javascript
const str = ‘𠮷野家で𩸽’;
function strlenEs2015(str) {
let chars = [];
for (let c of str) { chars.push(c); }
return chars.length;
}
console.log(‘ES2015’, strlenEs2015(str)); // 5
“`
`Array.from` でいけるとか。
内部的に for of 文のようなことをしているとのこと。
> * [なぜ絵文字を含む文字を1文字ずつに分けるのにArray.fromだけで十分なのか? – Qiita](http://qiita.com/alucky0707/items/697598e49ff56191c139)
“`javascript
const str = ‘𠮷野家で𩸽’;
function strlen(str) {
let ary = Array.from(str);
return ary.length;
}
console.log(strlen(str)); // 5
“`
で、`[…str].length` もローカルでトランスパイルしたら問題なかったというオチ。
See the Pen JavaScript Surrogate Pair by DriftwoodJP (@DriftwoodJP) on CodePen.
## 補遺
> * [Unicode のサロゲートペアとは何か – ひだまりソケットは壊れない](http://vividcode.hatenablog.com/entry/unicode/surrogate-pair)
> * [Unicode – Wikipedia](https://ja.wikipedia.org/wiki/Unicode#.E3.82.B5.E3.83.AD.E3.82.B2.E3.83.BC.E3.83.88.E3.83.9A.E3.82.A2)
[/markdown]