package myKanjiDemos; import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; public class MyStringToChars { // 文字列分解時のオプション public enum CharsNormalize { // ダミー NONE, // 半角カナを全角カナへ変換する HALF2FULL_KANA, // 文字と濁音・半濁音記号を1文字に統合する COMBININGVOICEMARK_KANA }; // 1文字リストの内容から文字列を生成する public static String makeStringFromList(List> parsedList) { StringBuilder sbRebuild = new StringBuilder(); sbRebuild.setLength(0); for(int pos=0; pos < parsedList.size(); pos++) { for(int idx = 0; idx < parsedList.get(pos).size(); idx++) { sbRebuild.appendCodePoint(parsedList.get(pos).get(idx)); } } return sbRebuild.toString(); } // 文字列を1文字ずつ分解してリストにする public static List> parseToCodepoints(String str, EnumSet normalize) { List> ans = new ArrayList>(); Integer currentCodepoint; Integer codepoint; for(int idx = 0; idx 65535) idx++; } return ans; } // 記号用ダイアクリティカルマーク判定 private static boolean isDiacriticalMarksSymbols(int codepoint) { boolean ans = false; if( (codepoint >= 0x20D0)&& (codepoint <= 0x20FF) ) ans = true; return ans; } // 異字体セレクタ判定 private static boolean isVariationSelectors(int codepoint) { boolean ans = false; if ( ((codepoint>=0xe0100)&&(codepoint<=0xe01ef)) || ((codepoint>=0xef00 )&&(codepoint<=0xef0f )) ) { ans = true; } return ans; } // 濁音半濁音記号判定 private static boolean isSoundmarkKana(int soundmarkCodepoint) { boolean ans = false; if(mapVoicemarkKana.containsKey(soundmarkCodepoint)) { ans = true; } return ans; } // かな濁音半濁音記号付き判定 private static boolean isKanaWithSoundmark(int kanaCodepoint) { boolean ans = false; if(mapKanaWithJudgeVoicemark.containsKey(kanaCodepoint)) { ans = !mapKanaWithJudgeVoicemark.get(kanaCodepoint); } return ans; } // 半角カナを全角カナへ正規化する private static Integer normalizationHalf2FullKana(int kanaCodepoint) { Integer ans = kanaCodepoint; if(mapHalf2FullKana.containsKey(kanaCodepoint)) { ans = mapHalf2FullKana.get(kanaCodepoint); } return ans; } // 結合文字の濁音・半濁音記号を正規化する private static Integer normalizationSoundmarkKana(int soundmarkCodepoint) { Integer ans = soundmarkCodepoint; if(mapVoicemarkKana.containsKey(soundmarkCodepoint)) { ans = mapVoicemarkKana.get(soundmarkCodepoint); } return ans; } // 文字の構成コードポイントを追加する private static void appendCharCodepoint(List> charlist, int codepoint) { if(charlist != null) { if (charlist.size()==0) { charlist.add(new ArrayList()); } charlist.get(charlist.size()-1).add(codepoint); } } // 文字を追加する private static void appendChar(List> charlist, int codepoint) { if(charlist != null) { charlist.add(new ArrayList()); charlist.get(charlist.size()-1).add(codepoint); } } // 濁音・半濁音記号を直前の文字の構成コードポイントとして追加する private static void mergeCharAndSoundmarkKana(List> charlist, int soundmarkCodepoint) { List targetChar; int kanaCodepoint; if(charlist.size()==0) { // 統合先の文字がないので単体のまま charlist.add( new ArrayList() ); charlist.get(0).add(normalizationSoundmarkKana(soundmarkCodepoint)); return; } targetChar = charlist.get(charlist.size()-1); kanaCodepoint = targetChar.get(targetChar.size()-1); if (isSoundmarkKana(kanaCodepoint)) { // 統合先の文字が濁音・半濁音記号なら単体文字追加にする charlist.add( new ArrayList() ); charlist.get(charlist.size()-1).add(normalizationSoundmarkKana(soundmarkCodepoint)); return; } if (isKanaWithSoundmark(kanaCodepoint)) { // 統合先の文字が濁音・半濁音記号付きなら単体文字追加にする charlist.add( new ArrayList() ); charlist.get(charlist.size()-1).add(normalizationSoundmarkKana(soundmarkCodepoint)); return; } // 統合先の文字の構成要素に構成コードポイントを追加 targetChar.add(normalizationSoundmarkKana(soundmarkCodepoint)); } // 濁音・半濁音記号付きの文字に正規化する private static void concatCharAndSoundmarkKana(List> charlist, int soundmarkCodepoint) { List targetChar; int kanaCodepoint; int newsoundmark; if(charlist.size()==0) { // 統合先の文字がないので単体のまま charlist.add( new ArrayList() ); charlist.get(0).add(normalizationSoundmarkKana(soundmarkCodepoint)); return; } targetChar = charlist.get(charlist.size()-1); kanaCodepoint = targetChar.get(targetChar.size()-1); if (isSoundmarkKana(kanaCodepoint)) { // 統合先の文字が濁音・半濁音記号なら単体文字追加にする charlist.add( new ArrayList() ); charlist.get(charlist.size()-1).add(normalizationSoundmarkKana(soundmarkCodepoint)); return; } if (isKanaWithSoundmark(kanaCodepoint)) { // 統合先の文字が濁音・半濁音記号付きなら単体文字追加にする charlist.add( new ArrayList() ); charlist.get(charlist.size()-1).add(normalizationSoundmarkKana(soundmarkCodepoint)); return; } // 統合先の文字のが濁音・半濁音記号を付与可能な場合は文字の差し替え newsoundmark = mapVoicemarkKana.get(soundmarkCodepoint); switch(newsoundmark) { case 0x309B: if (map309B.containsKey(kanaCodepoint)) { targetChar.remove(targetChar.size()-1); targetChar.add(map309B.get(kanaCodepoint)); } else { targetChar.add(newsoundmark); } break; case 0x309C: if (map309C.containsKey(kanaCodepoint)) { targetChar.remove(targetChar.size()-1); targetChar.add(map309C.get(kanaCodepoint)); } else { targetChar.add(newsoundmark); } break; default: targetChar.add(soundmarkCodepoint); break; } } private static Map mapVoicemarkKana = new HashMap() {{ put( 0x3099 , 0x309B ); // 結合文字濁音 put( 0x309A , 0x309C ); // 結合文字半濁音 put( 0x309B , 0x309B ); // 濁音 put( 0x309C , 0x309C ); // 濁音 put( 0xFF9E , 0x309B ); // ハーフワイド濁音 put( 0xFF9F , 0x309C ); // ハーフワイド半濁音 }}; private static Map mapKanaWithJudgeVoicemark = new HashMap() {{ put( 0x3094 , false); // ゔ put( 0x304C , false); // が put( 0x304E , false); // ぎ put( 0x3050 , false); // ぐ put( 0x3052 , false); // げ put( 0x3054 , false); // ご put( 0x3056 , false); // ざ put( 0x3058 , false); // じ put( 0x305A , false); // ず put( 0x305C , false); // ぜ put( 0x305E , false); // ぞ put( 0x3060 , false); // だ put( 0x3062 , false); // ぢ put( 0x3065 , false); // づ put( 0x3067 , false); // で put( 0x3069 , false); // ど put( 0x3070 , false); // ば put( 0x3071 , false); // ぱ put( 0x3073 , false); // び put( 0x3074 , false); // ぴ put( 0x3076 , false); // ぶ put( 0x3077 , false); // ぷ put( 0x3079 , false); // べ put( 0x307A , false); // ぺ put( 0x307C , false); // ぼ put( 0x307D , false); // ぽ put( 0x30F4 , false); // ヴ put( 0x30AC , false); // ガ put( 0x30AE , false); // ギ put( 0x30B0 , false); // グ put( 0x30B2 , false); // ゲ put( 0x30B4 , false); // ゴ put( 0x30B6 , false); // ザ put( 0x30B8 , false); // ジ put( 0x30BA , false); // ズ put( 0x30BC , false); // ゼ put( 0x30BE , false); // ゾ put( 0x30C0 , false); // ダ put( 0x30C2 , false); // ヂ put( 0x30C5 , false); // ヅ put( 0x30C7 , false); // デ put( 0x30C9 , false); // ド put( 0x30D0 , false); // バ put( 0x30D1 , false); // パ put( 0x30D3 , false); // ビ put( 0x30D4 , false); // ピ put( 0x30D6 , false); // ブ put( 0x30D7 , false); // プ put( 0x30D9 , false); // ベ put( 0x30DA , false); // ペ put( 0x30DC , false); // ボ put( 0x30DD , false); // ポ put( 0x30F7 , false); // ヷ put( 0x30F8 , false); // ヸ put( 0x30F9 , false); // ヹ put( 0x30FA , false); // ヺ put( 0x3046 , true ); // う put( 0x304B , true ); // か put( 0x304D , true ); // き put( 0x304F , true ); // く put( 0x3051 , true ); // け put( 0x3053 , true ); // こ put( 0x3055 , true ); // さ put( 0x3057 , true ); // し put( 0x3059 , true ); // す put( 0x305B , true ); // せ put( 0x305D , true ); // そ put( 0x305F , true ); // た put( 0x3061 , true ); // ち put( 0x3064 , true ); // つ put( 0x3066 , true ); // て put( 0x3068 , true ); // と put( 0x306F , true ); // は put( 0x3072 , true ); // ひ put( 0x3075 , true ); // ふ put( 0x3078 , true ); // へ put( 0x307B , true ); // ほ put( 0x30A6 , true ); // ウ put( 0x30AB , true ); // カ put( 0x30AD , true ); // キ put( 0x30AF , true ); // ク put( 0x30B1 , true ); // ケ put( 0x30B3 , true ); // コ put( 0x30B5 , true ); // サ put( 0x30B7 , true ); // シ put( 0x30B9 , true ); // ス put( 0x30BB , true ); // セ put( 0x30BD , true ); // ソ put( 0x30BF , true ); // タ put( 0x30C1 , true ); // チ put( 0x30C4 , true ); // ツ put( 0x30C6 , true ); // テ put( 0x30C8 , true ); // ト put( 0x30CF , true ); // ハ put( 0x30D2 , true ); // ヒ put( 0x30D5 , true ); // フ put( 0x30D8 , true ); // ヘ put( 0x30DB , true ); // ホ put( 0x30EF , true ); // ワ put( 0x30F0 , true ); // ヰ put( 0x30F1 , true ); // ヱ put( 0x30F2 , true ); // ヲ }}; private static Map mapHalf2FullKana = new HashMap() {{ put( 0xFF9E , 0x309B ); // Voicemark put( 0xFF9F , 0x309C ); // Voicemark put( 0xFFE9 , 0x2190 ); // ← put( 0xFFEA , 0x2191 ); // ↑ put( 0xFFEB , 0x2192 ); // → put( 0xFFEC , 0x2193 ); // ↓ put( 0xFFE8 , 0x2502 ); // │ put( 0xFFED , 0x25A0 ); // ■ put( 0xFFEE , 0x25CB ); // ○ put( 0x0020 , 0x3000 ); //   put( 0xFF64 , 0x3001 ); // 、 put( 0xFF61 , 0x3002 ); // 。 put( 0xFF62 , 0x300C ); // 「 put( 0xFF63 , 0x300D ); // 」 put( 0x003D , 0x30A0 ); // ゠ put( 0xFF67 , 0x30A1 ); // ァ put( 0xFF71 , 0x30A2 ); // ア put( 0xFF68 , 0x30A3 ); // ィ put( 0xFF72 , 0x30A4 ); // イ put( 0xFF69 , 0x30A5 ); // ゥ put( 0xFF73 , 0x30A6 ); // ウ put( 0xFF6A , 0x30A7 ); // ェ put( 0xFF74 , 0x30A8 ); // エ put( 0xFF6B , 0x30A9 ); // ォ put( 0xFF75 , 0x30AA ); // オ put( 0xFF76 , 0x30AB ); // カ put( 0xFF77 , 0x30AD ); // キ put( 0xFF78 , 0x30AF ); // ク put( 0xFF79 , 0x30B1 ); // ケ put( 0xFF7A , 0x30B3 ); // コ put( 0xFF7B , 0x30B5 ); // サ put( 0xFF7C , 0x30B7 ); // シ put( 0xFF7D , 0x30B9 ); // ス put( 0xFF7E , 0x30BB ); // セ put( 0xFF7F , 0x30BD ); // ソ put( 0xFF80 , 0x30BF ); // タ put( 0xFF81 , 0x30C1 ); // チ put( 0xFF6F , 0x30C3 ); // ッ put( 0xFF82 , 0x30C4 ); // ツ put( 0xFF83 , 0x30C6 ); // テ put( 0xFF84 , 0x30C8 ); // ト put( 0xFF85 , 0x30CA ); // ナ put( 0xFF86 , 0x30CB ); // ニ put( 0xFF87 , 0x30CC ); // ヌ put( 0xFF88 , 0x30CD ); // ネ put( 0xFF89 , 0x30CE ); // ノ put( 0xFF8A , 0x30CF ); // ハ put( 0xFF8B , 0x30D2 ); // ヒ put( 0xFF8C , 0x30D5 ); // フ put( 0xFF8D , 0x30D8 ); // ヘ put( 0xFF8E , 0x30DB ); // ホ put( 0xFF8F , 0x30DE ); // マ put( 0xFF90 , 0x30DF ); // ミ put( 0xFF91 , 0x30E0 ); // ム put( 0xFF92 , 0x30E1 ); // メ put( 0xFF93 , 0x30E2 ); // モ put( 0xFF6C , 0x30E3 ); // ャ put( 0xFF94 , 0x30E4 ); // ヤ put( 0xFF6D , 0x30E5 ); // ュ put( 0xFF95 , 0x30E6 ); // ユ put( 0xFF6E , 0x30E7 ); // ョ put( 0xFF96 , 0x30E8 ); // ヨ put( 0xFF97 , 0x30E9 ); // ラ put( 0xFF98 , 0x30EA ); // リ put( 0xFF99 , 0x30EB ); // ル put( 0xFF9A , 0x30EC ); // レ put( 0xFF9B , 0x30ED ); // ロ put( 0xFF9C , 0x30EE ); // ヮ put( 0xFF9C , 0x30EF ); // ワ put( 0xFF66 , 0x30F2 ); // ヲ put( 0xFF9D , 0x30F3 ); // ン put( 0xFF65 , 0x30FB ); // ・ put( 0xFF70 , 0x30FC ); // ー }}; private static Map map309C = new HashMap() {{ put( 0x306F , 0x3071 ); // ぱ put( 0x3072 , 0x3074 ); // ぴ put( 0x3075 , 0x3077 ); // ぷ put( 0x3078 , 0x307A ); // ぺ put( 0x307B , 0x307D ); // ぽ put( 0x30CF , 0x30D1 ); // パ put( 0x30D2 , 0x30D4 ); // ピ put( 0x30D5 , 0x30D7 ); // プ put( 0x30D8 , 0x30DA ); // ペ put( 0x30DB , 0x30DD ); // ポ }}; private static Map map309B = new HashMap() {{ put( 0x309D , 0x309E ); // ゞ put( 0x30FD , 0x30FE ); // ヾ put( 0x3046 , 0x3094 ); // ゔ put( 0x304B , 0x304C ); // が put( 0x304D , 0x304E ); // ぎ put( 0x304F , 0x3050 ); // ぐ put( 0x3051 , 0x3052 ); // げ put( 0x3053 , 0x3054 ); // ご put( 0x3055 , 0x3056 ); // ざ put( 0x3057 , 0x3058 ); // じ put( 0x3059 , 0x305A ); // ず put( 0x305B , 0x305C ); // ぜ put( 0x305D , 0x305E ); // ぞ put( 0x305F , 0x3060 ); // だ put( 0x3061 , 0x3062 ); // ぢ put( 0x3064 , 0x3065 ); // づ put( 0x3066 , 0x3067 ); // で put( 0x3068 , 0x3069 ); // ど put( 0x306F , 0x3070 ); // ば put( 0x3072 , 0x3073 ); // び put( 0x3075 , 0x3076 ); // ぶ put( 0x3078 , 0x3079 ); // べ put( 0x307B , 0x307C ); // ぼ put( 0x30A6 , 0x30F4 ); // ヴ put( 0x30AB , 0x30AC ); // ガ put( 0x30AD , 0x30AE ); // ギ put( 0x30AF , 0x30B0 ); // グ put( 0x30B1 , 0x30B2 ); // ゲ put( 0x30B3 , 0x30B4 ); // ゴ put( 0x30B5 , 0x30B6 ); // ザ put( 0x30B7 , 0x30B8 ); // ジ put( 0x30B9 , 0x30BA ); // ズ put( 0x30BB , 0x30BC ); // ゼ put( 0x30BD , 0x30BE ); // ゾ put( 0x30BF , 0x30C0 ); // ダ put( 0x30C1 , 0x30C2 ); // ヂ put( 0x30C4 , 0x30C5 ); // ヅ put( 0x30C6 , 0x30C7 ); // デ put( 0x30C8 , 0x30C9 ); // ド put( 0x30CF , 0x30D0 ); // バ put( 0x30D2 , 0x30D3 ); // ビ put( 0x30D5 , 0x30D6 ); // ブ put( 0x30D8 , 0x30D9 ); // ベ put( 0x30DB , 0x30DC ); // ボ put( 0x30EF , 0x30F7 ); // ヷ put( 0x30F0 , 0x30F8 ); // ヸ put( 0x30F1 , 0x30F9 ); // ヹ put( 0x30F2 , 0x30FA ); // ヺ }}; }