LoginSignup
6
3

More than 5 years have passed since last update.

Node.js で絵文字を使う時の注意点

Last updated at Posted at 2016-03-05

Node.js で絵文字を使った時に少し躓いたので

環境

$ node -v
v5.7.1

ダメな例

文字列に対して一文字ごとに操作したい場合、 charAtstr[i] で文字を取得したり、split("") で分離させたりすると思います。
しかし、絵文字が含まれていると結果がおかしくなります。

kuso.js
"use strict";

const emojiStr = "unko💩 うんこ";

// 一文字ごとに色を付けたい
const rainbow = [31, 32, 33, 34, 35, 36];
let rainbowPos = 0;

// 一文字ごとに切って色をつける
const colored = emojiStr.split("").map((c) => {
  let n = rainbow[
    (rainbow.length <= ++rainbowPos) ? (rainbowPos = 0) : rainbowPos
  ];
  return `\x1b[${n}m${c}\x1b[39m`;
}).join("");

console.log(colored);

実行結果がこちら
2016-03-04-184756_106x19_scrot.png
最悪ですね。

punycode.ucs2.decode / encode を用いる

そこで、標準モジュールである punycode の punycode.ucs2.decode, punycode.ucs2.encode 関数を使用すると、絵文字を含む文字列をいい感じに操作することが可能になります。

iikannji.js
"use strict";

const punycode = require("punycode");


const emojiStr = "star🌠 星";

// 一文字ごとに色を付けたい
const rainbow = [31, 32, 33, 34, 35, 36];
let rainbowPos = 0;

// decode で文字列をコード化
const colored = punycode.ucs2.decode(emojiStr).map((code) => {

  // コードから文字へ戻す
  let c = punycode.ucs2.encode([code]);

  let n = rainbow[
    (rainbow.length <= ++rainbowPos) ? (rainbowPos = 0) : rainbowPos
  ];

  return `\x1b[${n}m${c}\x1b[39m`;
}).join("");

console.log(colored);

実行結果がこちら
2016-03-04-184813_68x17_scrot.png
最高です。

まとめ

絵文字が含まれる文字列を操作する場合は punycode.ucs2.encode/decode を使用しましょう。
Array.from 使おう!(コメントより)

6
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3