Edited at

家族👨‍👩‍👦‍👦はreplaceされてしまうのか?あるいはZWJの話😂

More than 1 year has passed since last update.

こんにちは、@todokrです。これは絵文字 / Emoji Advent Calendar 2016 3日目の記事です。

さっそくですがクイズです。以下のJavaScriptのコードの実行結果はどうなるでしょうか?:kissing:


スクリーンショット 2016-12-03 0.23.09.png

(すぐお試しいただけるようgistにコードをアップしてみました)

...

...

...

結果はこちらです。

スクリーンショット 2016-12-03 0.23.02.png

なんと!ママが入れ替わってしまいました!:scream:

「家族」の1文字に対してreplace したのに何故でしょうか?

「なんだこの文字は!?」に遭遇したらやることはただひとつ、そう16進ダンプでバイナリを見ることです。1

まずはプレーンな「家族」の絵文字から見てみましょう:mag:

このようなテキストファイルを用意します。

スクリーンショット 2016-12-03 0.24.14.png

odコマンドでダンプした結果が以下です。

スクリーンショット 2016-12-03 0.24.20.png

エンコーディングはUTF-16なので2バイトずつで0xD83Dと0xDC6Aですね:grin:

先頭バイトの0xD83Dが上位サロゲートで、後続の下位サロゲート0xDC6Aと合わせて「家族」の絵文字を表現しています。

スクリーンショット 2016-12-03 0.42.10.png

'FAMILY' (U+1F46A)

ここまでは想定どおりです:relaxed:

次にママがreplaceされてしまったかわいそうな絵文字を見てみましょう。同じようにテキストファイルを用意します。

スクリーンショット 2016-12-03 0.24.26.png

同じくodコマンドで16進ダンプをしてみます。

スクリーンショット 2016-12-03 1.36.41.png

むむ!先ほどとは明らかに様子が違いますね!:frowning2:

落ち着いて見ていきましょう。

スクリーンショット 2016-12-03 0.24.47.png

0xD83D 0xDC68は'MAN' (U+1F468)なのでパパですね:man_tone1:

スクリーンショット 2016-12-03 0.24.53.png

0xD83D 0xDC69は'WOMAN' (U+1F469)でママです:woman_tone1:

スクリーンショット 2016-12-03 0.25.01.png

2つの0xD83D 0xDC66は'BOY' (U+1F466)で2人の息子たちを表していることが分かりました:relaxed:

スクリーンショット 2016-12-03 0.24.37.png

残った3つの0x200Dは何でしょうか?実はこれがZWJと呼ばれるものです。「ズウィッジ」と発音します。

スクリーンショット 2016-12-03 1.56.06.png

ZWJについてはこちらの動画に分かりやすくまとまっています。

ZWJ、ZERO WIDTH JOINERは絵文字同士をつなぐ接着剤として「1つの絵文字」を表現します。そのように接着された絵文字は複数の文字から成り立っているので、正確には「文字列」ですね。

先ほどの👨‍👩‍👦‍👦はじつは👨と👩、👦、ZWJからなる文字列だったため、replaceできてしまったわけです。このような文字列をZWJ Sequenceといいます。

多種多様な家族のあり方を表現するために、Unicodeはこのような仕組みを用意しているわけですね:relaxed:

家族以外にも、職業を表す絵文字や、アメリカのAd Councilが行ったいじめ防止キャンペーン「I Am a Witness」のアイコンであるEye in Speech BubbleなどがこのZWJを使って表現されています。

スクリーンショット 2016-12-03 2.13.34.png

ZWJを使った絵文字の一覧はUnicodeのドキュメント、Emoji ZWJ Sequences Catalogから確認できます。

スクリーンショット 2016-12-03 2.12.33.png

いやあ、絵文字っておもしろいですね:relaxed:

明日は@tokutoku393さんです:thumbsup:





  1. CotEditorの場合、16進ダンプするよりも簡単な方法があると@1024jpさんに教えていただきました。詳しくはコメント欄をご覧ください。たぶん他のエディタにもある機能かもしれません。EmacsとかEmacsとか。 ↩