🗿←こんな感じの絵文字を資料中に使うのが今の職場で流行ってます。
そういえば実務で絵文字を取り扱うシステムに携わったことがなかったので、興味本位で調べてみました。
ついでに、絵文字を含む文字列を1文字ずつ切り出すjavaのサンプルコードも作りました。
【絵文字の定義】
絵文字は符号化文字集合「Unicode」で定義されており、Unicodeの文字符号化方式である「UTF-8」「UTF-16」等で使用することができる。
(「符号化文字集合」とは「文字」と「文字に割り当てた番号」の対応表、「文字符号化方式」とは「文字に割り当てた番号」と「実際にコンピュータが扱う数字」の対応表のことである)
なお、「UFT-16」は狭義の「Unicode」として呼ばれることもある。
Unicodeは元々1~2バイト文字を定義していたが、世界中の文字を取り扱いたいという要望に応えるために4バイト文字を拡張領域として定義した。
絵文字は、この拡張領域に含まれる。
4バイト文字は、「上位サロゲート(2バイト)+下位サロゲート(2文字)」の組み合わせで定義される。
「上位サロゲート」は0xD800~0xDBFF(1024通り)、「下位サロゲート」は0xDC00~0xDFFF(1024通り)で定義され、何れも2バイト文字では使用しないコードであるため、表現が衝突することはない。
4バイト文字は定義当時は実際に扱われることが少なかったが、日本の携帯の絵文字の普及により一般的に使われるようになり、Webシステム等では無視できない存在となった。
【サンプルコード】
・コード
public class Sample {
public static void main(String args[]){
// 引数から「🚅Unicode🌏絵文字で遊んでみよう😮」を取得し表示→化ける
System.out.println("引数から取得:"+args[0]);
// 変数で直接4バイト文字込みの文字列を定義し表示→化けない
String str = "🚅Unicode🌏絵文字で遊んでみよう😮";
System.out.println("変数から取得:"+str);
// 何も考えず1文字ごと文字と文字コードを出力→4バイト文字は2文字扱い
for (int i = 0; i < str.length() ; i++) {
int code = (int)str.charAt(i);
String hex = Integer.toHexString(code);
System.out.println((i + 1) + "番目の文字:" + str.charAt(i) + " 16進数:" + hex);
}
// サロゲート文字で4バイト文字を判定し、正しく1文字ずつ切り出す
String upperSurStart = "d800";
String upperSurEnd = "dbff";
int fourByteMojiCount = 0;
for (int i = 0; i < str.length() ; i++) {
int mojiPos = i+1-fourByteMojiCount;
int code = (int)str.charAt(i);
String hex = Integer.toHexString(code);
String strOneMoji = "";
if (hex.compareTo(upperSurStart)>=0 && hex.compareTo(upperSurEnd)<=0) {
strOneMoji = str.substring(i,i+2);
i++;
fourByteMojiCount++;
} else {
strOneMoji = str.substring(i,i+1);
}
System.out.println(mojiPos + "番目の文字:" + strOneMoji);
}
}
}
・出力
引数から取得:??Unicode??絵文字で遊んでみよう??
変数から取得:🚅Unicode🌏絵文字で遊んでみよう😮
1番目の文字:? 16進数:d83d
2番目の文字:? 16進数:de85
3番目の文字:U 16進数:55
4番目の文字:n 16進数:6e
5番目の文字:i 16進数:69
6番目の文字:c 16進数:63
7番目の文字:o 16進数:6f
8番目の文字:d 16進数:64
9番目の文字:e 16進数:65
10番目の文字:? 16進数:d83c
11番目の文字:? 16進数:df0f
12番目の文字:絵 16進数:7d75
13番目の文字:文 16進数:6587
14番目の文字:字 16進数:5b57
15番目の文字:で 16進数:3067
16番目の文字:遊 16進数:904a
17番目の文字:ん 16進数:3093
18番目の文字:で 16進数:3067
19番目の文字:み 16進数:307f
20番目の文字:よ 16進数:3088
21番目の文字:う 16進数:3046
22番目の文字:? 16進数:d83d
23番目の文字:? 16進数:de2e
1番目の文字:🚅
2番目の文字:U
3番目の文字:n
4番目の文字:i
5番目の文字:c
6番目の文字:o
7番目の文字:d
8番目の文字:e
9番目の文字:🌏
10番目の文字:絵
11番目の文字:文
12番目の文字:字
13番目の文字:で
14番目の文字:遊
15番目の文字:ん
16番目の文字:で
17番目の文字:み
18番目の文字:よ
19番目の文字:う
20番目の文字:😮
・余談
引数から文字列を与えた時は4バイト文字が「??」に化けた。
引数はUnicodeではないのだろうか?
(実務ではフォームやファイルが入力となり、そこで文字コードの指定ができるので、別に気にする必要はないのだが…)
【その他(MySQLについて)】
・MySQLは5.5.3以降でないと4バイト文字を取り扱えない。
(5.5.3以降では「utf8mb4」という文字コードで取り扱える)
--------------------------
ソースコードを書くことが多くなってきたので、PC版のデザインを横幅なものに変更しました。