[AS3] 全角(2バイト)と半角(1バイト)を区別したバイト数の計算 [Edit]

2バイトの全角と1バイトの半角とを区別した文字のバイト数が、どのようにしたら求められるか考えてみましょう。

01 escapeMultiByte()関数を使う

まず、escapeMultiByte()関数でエスケープした文字列を調べることが考えられます。全角は9バイトでアルファベットは1バイトです。ただし、半角でも3バイトの記号などがあることに注意しなければなりません(下表001)。

trace(getBytesTotal_escapeMultiByte("くぁwせdrftgyふじこlp"));   // 出力: 21
スクリプト001■escapeMultiByte()関数でバイト数を調べる
function getBytesTotal_escapeMultiByte(_str:String):uint {
	var nCount:uint = 0;
	var nLength:int = _str.length;
	for (var i:uint = 0; i < nLength; i++) {
		nCount += (escapeMultiByte(_str.charAt(i)).length > 3) ? 2 : 1;
	}
	return nCount;
}

さらに、半角カナはエスケープしても全角と区別は困難です(表001)。予め半角カナが含まれないことさえ確かなら、この方法でも差し支えないでしょう。

表001■文字列のエスケープ例とバイト数
文字列例 エスケープ バイト数
%E3%81%82 9
a a 1
% %25 3
%EF%BD%B1 9

02 ByteArrayクラスを使う

Colin Moock氏は「GET NUMBER OF BYTES IN A UTF-8 STRING」と題するblog記事で、ByteArrayオブジェクトにより文字列のバイト数が得られることを紹介されました。さらに、永井勝則氏がFLASH-japanへの投稿で、そのスクリプトに手を加えられています。ByteArray.lengthプロパティでバイト数を求めるやり方です(スクリプト002)。半角カナは1バイトと数えられます。

trace(getBytesTotal_ByteArray("くぁwせdrftgyふじこlp"));   // 出力: 21
スクリプト002■ByteArrayクラスでバイト数を調べる
function getBytesTotal_ByteArray(_str:String):uint {
	var byteArray:ByteArray = new ByteArray();
	byteArray.writeMultiByte(_str, "shift-jis");
	return byteArray.length;
}

03 文字コードにより仕分けて数え上げる

実は、ステートメント数は増えるものの、ひと文字ずつコードを調べて数え上げる方が、処理としては速くなります(スクリプト003)。必要なら、文字コードをさらに細かく仕分けることもできます[*1]

trace(getBytesTotal_code("くぁwせdrftgyふじこlp"));   // 出力: 21
スクリプト003■文字コードを調べて数える
function getBytesTotal_code(_str:String):uint {
	var nCount:uint = 0;
	var nLength:int = _str.length;
	for (var i:uint = 0; i < nLength; i++) {
		var char_str:String = _str.charAt(i);
		var nCode:Number = char_str.charCodeAt(0);
		var bSingle:Boolean = (nCode < 0x7F) || (0xFF61 < nCode && nCode < 0xFF9F);
		nCount +=  bSingle ? 1 : 2;
	}
	return nCount;
}

参考までに、wonderflのテスト用スクリプトで、3つの手法を比べてみました。

Counting total bytes of characters to be distinguished between single and multi bytes - wonderfl build flash online


[*1] yoshiweb.NET「ActionScriptで文字判定」参照。

コメント

この記事にコメントを書く

記事に対するテクニカルな質問はご遠慮ください(利用規約)。

その他の記事