【Unity】 文字列に含まれる絵文字を判別する
お世話になっております。ぐーるです。
また久しぶりになってしまいました。
ずっと開発はしてて、RPGとカードゲームを2本同時に作成しているのですが、
このRPG作るのが凄く楽しいのです。
シナリオ、システム、グラフィック、キャラクター
全部自分で用意するのですが、
キャラクターの絵を描く、描いたキャラクターをいきいきと会話させる、
といった事だけでとても楽しい。
「こんな会話させよう」「こうしたらこう展開出来るな」
といったシーンを考えて実装してるだけで楽しいです。
(現在進捗率70%)
妄想癖が功を奏するなんて事もあるのだな、と思います。
閑話休題、今日はunityで絵文字の判別をする方法を共有しようかなと。
じゃあ対応する必要なくない?
使いたい、という要望があったり
外部サービスと連携していたりすると
対応する必要が出てきます。
Unicodeの絵文字って
Unicodeでは絵文字は上記ルールに沿って実現されています。
Unicode一つで表示出来るものもあれば、複数にまたがって表示しているものもあります。
これを一つ一つ判別する必要があります。
判別する方法として
- 正規表現
- 完全一致
の2つがあります。
正規表現パターンの方がオススメですが、
絵文字以外の文字を含めてしまう恐れがあります。
完全一致であれば、含めてしまう恐れが少なくなりますが、
追加があった場合、逐一入力する必要があります。
正規表現例
iOSで扱われるUnicode 6.0絵文字の判定をする正規表現 · GitHub
完全一致例
Unity-UI-emoji/info.txt at master · mcraiha/Unity-UI-emoji · GitHub
実装
完全一致で実装する場合のコード例を共有します。
絵文字コードをまるっとソースに入れちゃってますが、
これはブログ用の実装で、プロジェクトにするならTextAssetsなど
の方が管理はしやすいでしょう。
また、絵文字コード表は全ては網羅出来ていないと思われますので、ご了承ください。
コード例)
// inputからEmojiを取り除いた文を返却する public static string RemoveEmojiString(string inputString) { int i = 0; string firstString = null; string secondString = null; string threeString = null; string fourString = null; StringBuilder sb = new StringBuilder(); var uint32Size = sizeof(UInt32); // unicode byte配列に文字列を変換 byte[] unicodeBytes = Encoding.Unicode.GetBytes(inputString); // unicode配列からUTF32配列に変換 var utf32Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF32, unicodeBytes); // 配列の長さ int length = utf32Bytes.Length / uint32Size; while (i < length) { // 1文字目をチェック firstString = BitConverter.ToUInt32(utf32Bytes, i * uint32Size).ToString("X4"); // 2文字目までつなげてチェック if (i < (length - 1)) { secondString = firstString + "-" + BitConverter.ToUInt32(utf32Bytes, (i + 1) * uint32Size).ToString("X4"); } // 4文字目までつなげてチェック if (i < (length - 3)) { threeString = BitConverter.ToUInt32(utf32Bytes, (i + 2) * uint32Size).ToString("X4"); fourString = secondString + "-" + threeString + "-" + BitConverter.ToUInt32(utf32Bytes, (i + 3) * uint32Size).ToString("X4"); } // 後ろから文字コード表と合わせてチェックして一致してたら絵文字と判断して読み飛ばす if (EMOJI_CODES.Any(e => e.Equals(fourString))) { i += 4; } else if (EMOJI_CODES.Any(e => e.Equals(secondString))) { i += 2; } else if (EMOJI_CODES.Any(e => e.Equals(firstString))) { i += 1; } else { // 正しい文字だけ投入 sb.Append(Char.ConvertFromUtf32(BitConverter.ToInt32(utf32Bytes, i * uint32Size))); i += 1; } } return sb.ToString(); } // 絵文字コード一覧表 public static readonly string[] EMOJI_CODES = { "1F004", // 略 ~~~~~~~~ };
絵文字コード一覧表をそのまま載せるとあまりにソースが長くなるので別ファイルにしました。
あとがき
以上で絵文字の判別が出来ます。
コード見ると「はいはい、まあそうだよね」って感じですよね。
軽く調べるとサロゲートペアだけ判別すればいいよ、なんて
乱暴なコードもあったりして、ちょっと気になるなと思った次第です。
次はUnity1Weekの記事になりそうです。
うーん、もうちょっと更新したい。