2011年5月1日日曜日

全角・半角判定(Java)

文字列を限られたスペースの中で表示する場合, たとえば, Webサイトや携帯電話内, 文字数に加えて全角・半角を意識しなければならない。

全角・半角で, 文字の大きさが違うとともに, 全角半角を組み合わせると, 文字の間のスペースが微妙に違ったりする。記号なども加えると, 一層面倒である。

しかし, 単純にJavaのプログラムで文字数を数えると, String.length() だと全角も半角も同じ文字数を返す

ex)
str = "ゆきりん";     // All 全角
str2 = "Yuki";          //  All 半角
str3 = "第3期生";   // 全角・半角混じり

str.length();
str2.length();
str3.length();   //これらいずれも, 4を返す。

といったように,  length() メソッドでは, 区別できない。
そして文字数で区別して表示させると, まったくもってそろわないことになる。

そこで, 今回は正規表現を使って, 半角・全角を処理する方法を考えてみた。

1. 全角のみで構成されている文字列を "[^ -~。-゚]* を使って判定 isZenkaku ()
2. 1の中でtrue ではない文字列で, その文字列を1文字1文字を取り出して, 上のisZenkaku()を利用して, その中に, 一つでもtrue があれば, 全角・半角混じりの文字列 (includeZenkaku)
3. それ以外は, All 半角

それを判定するのが validateChars

最後に1文字, 1文字チェックして全角であれば, BitSet のbitをたてるcharsCheck 

こちらのコードは, GitHub に登録しました。
DJ110GitHub

サンプル(全角・半角 Utility)
--------------------------------------------------------------------------------------

package com.atmarkplant.util.chars;

import java.util.BitSet;

public class Zenkaku
{
/**
* Whether str is all zentaku characters or not.
* @param str Target characters
* @return True if str is all zenkaku, false if not
*/
public boolean isZenkaku ( String str )
{
// Regular expression.
return str.matches("[^ -~。-゚]*");
}

/**
* Whether str includes zentaku or not.
* @param str Target characters
* @return True if str includes zentaku, false if not.
*/
public boolean includeZenkaku ( String str )
{
boolean ret_val = false;
for( char ch : str.toCharArray())
{
char chs[] = new char[1];
chs[0] = ch;

String st = new String(chs);
if ( isZenkaku ( st ) )
{
ret_val = true;
}
}
return ret_val;
}

/**
* Check str includes zenkaku or hankaku.
* @param str
* @return BitSet(if the character is zenkaku, set bit)
*/
public BitSet charsCheck ( String str )
{
BitSet ret_val = new BitSet();

int count = 0;
for( char ch : str.toCharArray())
{
char chs[] = new char[1];
chs[0] = ch;

String st = new String(chs);
if ( isZenkaku ( st ) )
{
ret_val.set( count );
}
count++;
}
return ret_val;
}

/**
* Return what kind of characters set?
* @param str Target characters
* @return 0: All hankaku, 1: All zenkaku,
*/
public int validateChars ( String str )
{
int ret_val = 0;
if ( isZenkaku ( str ) )
{
// All zenkaku.
ret_val = 1;
}
else if ( includeZenkaku( str ) )
{
// At least one character is zenkaku.
ret_val = 2;
}
return ret_val;
}
}


テストプログラム

package com.atmarkplant.util.chars;

import java.util.BitSet;

public class ZenkakuTest
{

/**
* @param args
*/
public static void main(String[] args)
{
Zenkaku zenkaku = new Zenkaku();

// Test chars.
String str = "渡辺麻友";
String str2 = "18番";

String str3 = "AKB48";

// まず文字数のチェック
System.out.println ( str + " is :" + str.length());
System.out.println ( str2 + " is :" + str2.length());
System.out.println ( str3 + " is :" + str3.length());

// 全角チェック
System.out.println( zenkaku.isZenkaku( str ) ? "全角です" : "半角が入っています");
System.out.println( zenkaku.isZenkaku( str2 ) ? "全角です" : "半角が入っています");

// 半角チェック
System.out.println( !zenkaku.includeZenkaku( str2 ) ? "半角です" : "全角が入っています");
System.out.println( !zenkaku.includeZenkaku( str3 ) ? "半角です" : "全角が入っています");

// 3パターンに分類
switch ( zenkaku.validateChars( str3 ) )
{
case 0:
System.out.println("半角です");
break;
case 1:
System.out.println("全角です");
break;
case 2:
System.out.println("半角全角混じってます");
break;
}

// 何で構成されているのか?
BitSet bits = zenkaku.charsCheck( str2 );

bits.length();

for (int i = 0; i < bits.length(); i++ )
{
if ( bits.get( i ) )
{
System.out.print("全");
}
else
{
System.out.print("半");
}
}
}
}

実行結果)

渡辺麻友 is :4
18番 is :3
AKB48 is :5
全角です
半角が入っています
全角が入っています
半角です
半角です
半半全

1 件のコメント:

  1. はじめまして!
    今日、プログラミングで行き詰まってこの記事を参考にさせて頂きました^^
    かなり行き詰まっていたため、大変参考になりました。
    ありがとうございました!

    返信削除