iモード絵文字をSJIS形式からUnicode形式に変換するPHPサンプル
Tweet
今回は、iモード絵文字をSJISバイナリ形式から、Unicodeテキスト入力(&#xxxx;)形式に変換するPHPのサンプルコードをご紹介します。
文字コード変換や、DBに格納する際など、SJISバイナリ形式では、文字化けなどの問題が起こるケースが多々あります。
そんな時には下記のコードでUnicodeテキスト入力形式に変換することで、データがぐっと扱いやすくなります。
$str = '[SJISバイナリ絵文字コードを含む文字列]';
// 文字コードを設定
mb_internal_encoding('SJIS');
mb_regex_encoding('SJIS');
// 正規表現を定義
$sjis = '[\\x81-\\x9F\\xE0-\\xF7\\xFA-\\xFC][\\x40-\\x7E\\x80-\\xFC]
|[\\x00-\\x7F]|[\\xA1-\\xDF]'; // 実際には1行で入力
$emoji = '[\\xF8\\xF9][\\x40-\\x7E\\x80-\\xFC]';
$pattern = "/\\G((?:$sjis)*)(?:($emoji))/";
// 絵文字を検索
preg_match_all($pattern, $str, $arr); // $arr[2]に対象絵文字が格納される
// 絵文字を置換
$rep_arr = array();
foreach($arr[2] as $value) {
$emoji_cd = unpack("C*", $value);
$hex = dechex($emoji_cd[1]) . dechex($emoji_cd[2]);
$dec = hexdec($hex);
if (63647 <= $dec AND $dec <= 63740) {
// 絵文字No.1 ~ No.94
$dec = $dec - 4705;
} elseif (63872 <= $dec AND $dec <= 63996) {
// 絵文字No.118 ~ No.166、拡1~拡76
$dec = $dec - 4773;
} elseif ((63808 <= $dec AND $dec <= 63817) OR
(63824 <= $dec AND $dec <= 63826) OR
(63829 <= $dec AND $dec <= 63831) OR
(63835 <= $dec AND $dec <= 63838) OR
(63858 <= $dec AND $dec <= 63870)) {
// 絵文字No.95 ~ No.117、No.167 ~ No.176
$dec = $dec - 4772;
} else {
continue;
}
$replacement = '&#' . strtoupper(dechex($dec)) . ';';
$str = mb_ereg_replace($value, $replacement, $str);
}
// 置換処理
$str = strtr($str, $rep_arr);
// 出力
echo $str;
※ソースはSJISで記述してください
※表示の都合上改行を入れている行があることにご注意ください
実行例:
逆変換(Unicode形式→SJIS形式)のサンプルは、また後日ご紹介させていただきます。
追記:
逆変換の記事も書きました。下記リンクをご参照ください。
関連:
9月 8th, 2009 at 14:49:23
[…] http://ke-tai.org/blog/2007/11/23/iemoji_conv1/この記事が役立ちます。 […]
2月 5th, 2010 at 11:10:30
こんにちは。
サンプル使わせてもらいました!
この記事に限らず、いつもとても助かってます。
ところでサンプルコード内の↓
————————
$replacement = ‘&#’ . strtoupper(dechex($dec)) . ‘;’;
————————
「x」が足りなくないですか?
$replacement = ‘&#x’ ~
これでバッチリ表示されました!
取るに足らないところですが、今さらながら一応ご報告を。
10月 21st, 2010 at 17:13:08
はじめまして。非常に参考にさせていただいています。
これと同じように、
softbank絵文字をSJISバイナリ形式から、Unicodeテキスト入力(&#xxxx;)形式に変換する。
のサンプルは無いでしょうか。