Codin’ In The Free World

2010-01-21

[] ActionScriptでの日本語文字コード変換

ActionScriptのByteArrayクラスにはreadMultiByteとwriteMultiByteというメソッドがあり、

こいつを使えば、日本語の文字コードも変換できます。

ということになっているのですが、環境によって動作が不安定なようです。


実際に、自分もこれらのメソッドを利用していて、

Leopardで通ってたテストがSnow Leopard(64bitモード)で実行したらこけるという場面に遭遇しました。

原因(SDKのバージョンとか, JDKが64bitだとどうとか)はまだ探りきれてません。


さらに、半角カナの扱いなど、日本語独特の問題もありますし、今後も適切なメンテが行われるか分かりません。

(というかそもそも、バイト列を扱う機能と、文字コードの変換を扱う機能を同じクラスにしてしまうのはいかがなものか)

そんなわけで、as3jcodeを書いてみました。


http://github.com/lyokato/as3jcode


サポートする文字コード

  • UTF-8
  • UTF-16
  • EUC-JP
  • ISO-2022-JP
  • Shift_JIS

UTF-16はByteArray.(read|write)Multibyteに"UNICODE"を指定すれば動くとは思います。

日本語文字コードならともかく、さすがにコレをちゃんとサポートしてないということはないと思いますが、

今回は、UTF-16ベースで半角と全角のカタカナの変換処理などもしたかったので、

自分で書いてしまいました。

使い方

ByteArrayのオブジェクトからByteArrayのオブジェクトを生成します。

import org.coderepos.text.encoding.Jcode;

// utf-8のByteArrayオブジェクトからEUC-JPにコンバートしたByteArrayオブジェクトを取得
var eucBytes:ByteArray = Jcode.utf8_euc(utf8Bytes);

// 同様にISO-2022-JPに変換
var jisBytes:ByteArray = Jcode.utf8_jis(utf8Bytes);

// 同様にShift_JIS
var jisBytes:ByteArray = Jcode.utf8_sjis(utf8Bytes);

// 同様にUTF-16
var utf16Bytes:ByteArray = Jcode.utf8_utf16(utf8Bytes);

// その他も、メソッド名を見ればだいたい分かると思います。
tf8Bytes  = Jcode.euc_utf8(eucBytes);
utf8nBytes = Jcode.euc_utf8n(eucBytes);
utf8Bytes  = Jcode.jis_utf8(jisBytes);
utf8nBytes = Jcode.jis_utf8n(jisBytes);
utf8Bytes  = Jcode.sjis_utf8(sjisBytes);
utf8nBytes = Jcode.sjis_utf8n(sjisBytes);
utf8Bytes  = Jcode.utf16_utf8(sjisBytes);
utf8nBytes = Jcode.utf16_utf8n(sjisBytes);
jisBytes  = Jcode.euc_jis(eucBytes);
sjisBytes = Jcode.euc_sjis(eucBytes);
eucBytes  = Jcode.jis_euc(jisBytes);
sjisBytes = Jcode.jis_sjis(jisBytes);
eucBytes  = Jcode.sjis_euc(sjisBytes);
jisBytes  = Jcode.sjis_jis(sjisBytes);

ActionScriptではSystem.useCodePageなどを触らない限り、

基本的にはUTF-8が基準になります。

UTF-8のStringからByteArrayのオブジェクトを作りたいときは次のようにします。

var bytes:ByteArray = new ByteArray();
bytes.writeUTFBytes("日本語の文字列。これはUTF-8");

なので、例えば文字列をEUC-JPに変換したいときは次のようになります。

var bytes:ByteArray = new ByteArray();
bytes.writeUTFBytes("日本語の文字列。これはUTF-8");
var eucBytes:ByteArray = Jcode.utf8_euc(bytes);

UTF-8を軸にした変換はよくありますし、

上のように毎回ByteArrayを準備するのもめんどくさいので、

「UTF-8の文字列から他の文字コードのバイト列へ変換」,

「他の文字コードのバイト列からUTF-8の文字列へ変換」だけは

特別にメソッドを用意しています。

ar eucBytes:ByteArray  = Jcode.to_euc("日本語");
var jisBytes:ByteArray  = Jcode.to_jis("日本語");
var sjisBytes:ByteArray = Jcode.to_sjis("日本語");

var utf8String:String = Jcode.from_euc(eucBytes);
var utf8String:String = Jcode.from_jis(jisBytes);
var utf8String:String = Jcode.from_sjis(sjisBytes);


半角カタカナを使うとき。

h2z(hankaku to zenkaku)メソッドで半角カタカナを全角カタカナに変換できます

UTF-8の文字列で渡すと、変換されたUTF-8の文字列が返ります。

var utf8String:String = Jcode.h2z("アイウエオ");
// utf8String -> "アイウエオ".

あとはvalidationとか。

f (Jcode.is_hiragana(utf8string)) {
  ...
}

if (Jcode.is_zenkaku_katakana(utf8string)) {
  ...
}

if (Jcode.is_hankaku_katakana(utf8string)) {
  ...
}

// zenkaku and hankaku katakana
if (Jcode.is_katakana(utf8string)) {
  ...
}

とりあえず現状はこんな感じ。

nisyunisyu 2010/02/16 12:02 はじめまして。
使いやすそうですね!早速試してみたいと思います。
いままで無かったんですよね。。こういうの。
・・ちなみに Jcode.h2z の逆で Jcode.z2h は無いようですが、つけれないものでしょうか?

lyokatolyokato 2010/02/16 15:49 個人的には、「受け取った文書の中に半角カナがあり、全角に変換したい」ということはあっても、
「自分で進んで全角を半角にしたい」というユースケースは思い浮かばなかったので
あえてその機能を付けないでいました。

とはいえ、携帯端末がらみのワークアラウンドなどで必要になるかもしれませんし、要望があるならば、
ということで足しておきました。

http://github.com/lyokato/as3jcode/commit/043a2cb5a22a2b5d6c1d23fe2c54e5e2c9aa25b2

github上の最新バージョンで使えるようになっています。

nisyunisyu 2010/02/17 10:28 おおおっ 早速、、、ありがとうございます!
実は銀行絡みで以前に困ったことがあったので聞いてみた次第です。

早速使ってみようと思います!

lyokatolyokato 2010/02/17 10:48 なるほど。
銀行絡みは確かにレガシー対応が大変そうですね。


ビルドファイルの対応を忘れていたので、先程
bin/as3jcode-1_0_2.swc
としてパブリッシュしておきました。

sirazisusirazisu 2013/12/17 23:48 chromeでreadMultiByteの"unicode"指定が上手くいかなくて
困っていたので、とても助かりました!
ありがとうございます!

gingeralegingerale 2016/02/12 14:25 iOS上でのreadMultiByteが上手く動かなったので助かりました!

ただ、as3jcode.swcをインポートしたプロジェクトをiOS向けにリリースビルドしようとすると、
完了までに2時間かかるようになってしまいました。(元は5分程度)
この現象はご認識されていますでしょうか?

ためしてみるとインポートしただけでは遅くならず、Jcode.from_sjisを使った場合に遅くなっているようです。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/lyokato/20100121/1264083565