    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.fukurou.util;
    017
    018/**
    019 * KanaFilter.java は、半角カタカナを全角カタカナに変換するフィルターツールです。
    020 *
    021 * 大元の出典は、『CJKV日中韓越情報処理』のフィルターアルゴリズムです。
    022 * 濁点や半濁点の正しい処理も含まれています。
    023 *
    024 * @version  4.0
    025 * @author   Kazuhiko Hasegawa
    026 * @since    JDK5.0,
    027 */
    028public final class KanaFilter {
    029
    030        // uFF61 から uFF9Fまでの半角カナに対応(u3002 ～ u309C)
    031        private static final char ZEN_KANA[] = {
    032                '。','「','」','、','・',
    033                'ヲ','ァ','ィ','ゥ','ェ','ォ',
    034                'ャ','ュ','ョ','ッ','ー',
    035                'ア','イ','ウ','エ','オ',
    036                'カ','キ','ク','ケ','コ',
    037                'サ','シ','ス','セ','ソ',
    038                'タ','チ','ツ','テ','ト',
    039                'ナ','ニ','ヌ','ネ','ノ',
    040                'ハ','ヒ','フ','ヘ','ホ',
    041                'マ','ミ','ム','メ','モ',
    042                'ヤ','ユ','ヨ',
    043                'ラ','リ','ル','レ','ロ',
    044                'ワ','ン','゛','゜'
    045        };
    046
    047        /**
    048         * すべてが staticメソッドなので、コンストラクタを呼び出さなくしておきます。
    049         *
    050         */
    051        private KanaFilter() {}
    052
    053        /**
    054         * 半角カタカナを全角カタカナに
    055         *
    056         * 半角カタカナの定義は、\uFF61 から \uFF9F までです。
    057         *
    058         * @param   in 半角カタカナ文字列
    059         *
    060         * @return  全角文字列
    061         */
    062        public static String han2zen( final String in ) {
    063                int ixIn  = 0;
    064                int ixOut = 0;
    065                int len = in.length();
    066                char[] input = in.toCharArray();
    067                char[] output = new char[len + 1];
    068
    069                while( ixIn < len ) {
    070                        // 半角カタカナの範囲
    071                        if( input[ixIn] >= '\uFF61' && input[ixIn] <= '\uFF9F' ) {
    072                                if( ixIn + 1 >= len ) {
    073                                        output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
    074                                }
    075                                else {
    076                                        // 濁点(ヴ)
    077                                        if( input[ixIn+1] == 'ﾞ' ||
    078                                                        input[ixIn+1] == '\u3099' ||
    079                                                        input[ixIn+1] == '゛' ) {
    080                                                if( input[ixIn] == 'ｳ' ) {
    081                                                        output[ixOut++] = 'ヴ' ;
    082                                                        ixIn +=2 ;
    083                                                }
    084                                                else {
    085                                                        // 濁点(ガ～ド、バ～ボ)
    086                                                        if( input[ixIn] >= 'ｶ' &&
    087                                                                        input[ixIn] <= 'ﾄ' ||
    088                                                                        input[ixIn] >= 'ﾊ' &&
    089                                                                        input[ixIn] <= 'ﾎ' ) {
    090                                                                output[ixOut] = ZEN_KANA[input[ixIn] - '\uFF61'];
    091                                                                output[ixOut++]++;
    092                                                                ixIn +=2 ;
    093                                                        }
    094                                                        else {
    095                                                                output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
    096                                                        }
    097                                                }
    098                                        }
    099                                        else {
    100                                                // 半濁点(パ～ポ)
    101                                                if( input[ixIn+1] == 'ﾟ' ||
    102                                                                input[ixIn+1] == '\u309A' ||
    103                                                                input[ixIn+1] == '゜' ) {
    104                                                        if( input[ixIn] >= 'ﾊ' &&
    105                                                                        input[ixIn] <= 'ﾎ' ) {
    106                                                                output[ixOut] = ZEN_KANA[input[ixIn] - '\uFF61'];
    107                                                                output[ixOut++]+=2;
    108                                                                ixIn +=2 ;
    109                                                        }
    110                                                        else {
    111                                                                output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
    112                                                        }
    113                                                }
    114                                                else {
    115                                                        output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
    116                                                }
    117                                        }
    118                                }
    119                        }
    120                        else {
    121                                output[ixOut++] = input[ixIn++];
    122                        }
    123                }
    124                String output_string = new String( output );
    125                return output_string.substring(0,ixOut);
    126        }
    127
    128        /**
    129         * テスト用 mainメソッド
    130         *
    131         * @param       args    変換元文字列
    132         */
    133        public static void main( final String[] args ) {
    134                System.out.println( KanaFilter.han2zen( args[0] ) );
    135        }
    136
    137}