    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   inStr 半角カタカナ文字列
    059         *
    060         * @return  全角文字列
    061         * @og.rtnNotNull
    062         */
    063        public static String han2zen( final String inStr ) {
    064                int ixIn  = 0;
    065                int ixOut = 0;
    066                final int len = inStr.length();
    067                final char[] input = inStr.toCharArray();
    068                char[] output = new char[len + 1];
    069
    070                while( ixIn < len ) {
    071                        // 半角カタカナの範囲
    072                        if( input[ixIn] >= '\uFF61' && input[ixIn] <= '\uFF9F' ) {
    073                                if( ixIn + 1 >= len ) {
    074                                        output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
    075                                }
    076                                else {
    077                                        // 濁点(ヴ)
    078                                        if( input[ixIn+1] == 'ﾞ' ||
    079                                                        input[ixIn+1] == '\u3099' ||
    080                                                        input[ixIn+1] == '゛' ) {
    081                                                if( input[ixIn] == 'ｳ' ) {
    082                                                        output[ixOut++] = 'ヴ' ;
    083                                                        ixIn +=2 ;
    084                                                }
    085                                                else {
    086                                                        // 濁点(ガ～ド、バ～ボ)
    087                                                        if( input[ixIn] >= 'ｶ' &&
    088                                                                        input[ixIn] <= 'ﾄ' ||
    089                                                                        input[ixIn] >= 'ﾊ' &&
    090                                                                        input[ixIn] <= 'ﾎ' ) {
    091                                                                output[ixOut] = ZEN_KANA[input[ixIn] - '\uFF61'];
    092                                                                output[ixOut++]++;
    093                                                                ixIn +=2 ;
    094                                                        }
    095                                                        else {
    096                                                                output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
    097                                                        }
    098                                                }
    099                                        }
    100                                        else {
    101                                                // 半濁点(パ～ポ)
    102                                                if( input[ixIn+1] == 'ﾟ' ||
    103                                                                input[ixIn+1] == '\u309A' ||
    104                                                                input[ixIn+1] == '゜' ) {
    105                                                        if( input[ixIn] >= 'ﾊ' &&
    106                                                                        input[ixIn] <= 'ﾎ' ) {
    107                                                                output[ixOut] = ZEN_KANA[input[ixIn] - '\uFF61'];
    108                                                                output[ixOut++]+=2;
    109                                                                ixIn +=2 ;
    110                                                        }
    111                                                        else {
    112                                                                output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
    113                                                        }
    114                                                }
    115                                                else {
    116                                                        output[ixOut++] = ZEN_KANA[input[ixIn++] - '\uFF61'];
    117                                                }
    118                                        }
    119                                }
    120                        }
    121                        else {
    122                                output[ixOut++] = input[ixIn++];
    123                        }
    124                }
    125                return new String( output,0,ixOut );                    // 6.1.1.0 (2015/01/17) refactoring
    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}