EmojiSharpを使って文章中の識別子を絵文字に変換する
あすかです。
Mastodonクライアントを作っていると、ところどころ、変な文字に出会ったりしませんか?
この:white_check_mark:
というものは、何でしょうか。
実はこれ、Unicode絵文字を表示する命令で、「white_check_mark
という名前の絵文字を表示して!」といった意味合いなのです。
対応するソフトが、この:white_check_mark:
を絵文字に変換して、✅という文字を出力します。
おいおい絵文字といっても画像かよ、と思われた方もいらしてるかもしれませんが、Unicode絵文字は、れっきとした文字コードなのです。
「あ」や「い」のような文字と同じように表現することができます。
例えば、さっきの✅は、2705
という文字コードで表されます。
Mastodon、GitHub、Qiita、Twitterなどは独自の画像を使っているようです。(うち少なくともMastodonとTwitterは、絵文字の文字コードであっても画像に変換されるようです)
ここで一覧を見ることもできます。
Full Emoji List, v5.0
さて、文字コードで表された絵文字✅を表示するだけならどのソフトでもできますが、:white_check_mark:
を✅に変換する作業は、ソフトが対応していないとできません。
今回は、それをC#でやってみようというおはなしです。
EmojiSharpをUWPに導入する
:white_check_mark:
を2705
に変換するといった対照表を自分で全部作らなきゃいけないの?
一覧見てると数多いしきついよ~!
大丈夫です、EmojiSharpというのがあります。感謝っ‥‥!圧倒的感謝っ‥‥!
まず、新しくUWPプロジェクトを作成します。そして、さーーっそくInstall-Package
します!
Install-Package EmojiSharp
さーーっそくusing EmojiSharp
します!
わーいわーい!絵文字パラダイスだー!!!あれ?
(^ω^)ペロペロ
(^ω^)ペロペロ
ん?
nugetパッケージ消してインストールし直し!
(^ω^)ペロペロ
あれ?
(´・ω・`)
ちょっと調べたのですが、これ、.NET Framework基板のコンソールアプリならエラーは出ませんでしたが、UWPだとなぜかエラーが出ます。
なぜなんでしょう。
一体なぜなんでしょう。
宇宙の神秘でございますね。
というわけで、GitHubからソースを拝借してUWPプロジェクトの一部にしてしまいます。
コピペするソースはEmoji.cs
だけで十分です。
https://github.com/jmazouri/EmojiSharp/blob/master/EmojiSharp/Emoji.cs
ただ、このファイルはソースがバカ長いので、Rawを表示しまして、
https://raw.githubusercontent.com/jmazouri/EmojiSharp/master/EmojiSharp/Emoji.cs
こちらからCtrl+A
とCtrl+C
とCtrl+V
すると楽です。
UWPプロジェクト内の適当なところにEmoji.cs
というファイル作って、ソースを貼り付けます。
1ファイルだけなので楽ですね。EmojiSharp
が依存しているパッケージもないですし。
文字列中の命令を絵文字に変換する
さっそくプログラムです。正規表現を使って:
で囲まれた英数字を抽出し、絵文字辞書を反復して文字コードに変換しています。
変換のコア部分
正規表現で抽出したwhite_check_mark
が、絵文字のDictionaryEmojiSharp.Emoji.All
のkeyとして存在することが確認できたあとの処理がここです。
肝心の文字コードは、DictionaryのValueにあるUnified
プロパティに、文字列として保存されております。
ここで注意することは、複数の文字で1つの絵文字を表現していることがあるという点です。EmojiSharpでは、文字コードを2バイトずつ「-」で区切っていますので、まずそれをSplit
します。
newString
という変数には、絵文字の文字コードを絵文字に変換した結果が入ります。
つまり、2705
を✅に変換した後の✅がnewString
に入る感じですね。
最後に元の文字列をReplace
しておわりです。
実行結果
絵文字になりました。やったーわーい!
一部の文字は絵文字にならず、←こういう文字になってしまうことがありますが、それはUWP、ひいてはフォントがその絵文字に対応していないってことなので、あきらめて独自の画像用意するしかなさそうです。南無
追記
foreach
がネストしてるので、Linq強化版作ってみました。
ただ、ここまでするならforeach
ネストしてる方がまだ読みやすい気も‥‥
SelectMany
あたりで切って、foreach (Match myMatch in succeedMatches)
を消す程度でも十分かなぁ。