ヘボン式変換 たたき台 - java 2014/01/08
2014/01/18

追記リリースしました!
「文章」を「ヘボン式ローマ字」に変換ツール(β)


前回、プログラマメモ2: 日本語の文章をローマ字に変換したいなと。- javaで、ヘボン式変換したかったのだけど、それもならずだったので、チャレンジ。

意外と、公開している人がいたので、ちょっと参考にしてみました。


ヘボン式の説明は

歴史としては、かなり古いみたいですね。

「ヘボン式ローマ字とは、1867年に出版されたヘボンの「和英語林集成」という和英語辞典で使われた綴りを元に羅馬字会、ローマ字ひろめ会が修正を加え、ローマ字ひろめ会が1908年に発表したもの。」

とありました。

というわけで、javaプログラム。
すでにjavascriptの実装をみてしまったので、ちょっとアプローチの仕方をかえてみました。


package t022; import java.util.HashMap; import java.util.Map; import com.ibm.icu.text.Transliterator; public class Test5 { static class HebonConvert { static Map<String, String> map = new HashMap<String, String>(); static { map.put("ッ", "xtu"); map.put("っ", "xtu"); map.put("きゃ", "KYA"); map.put("きゅ", "KYU"); map.put("きょ", "KYO"); map.put("しゃ", "SHA"); map.put("しゅ", "SHU"); map.put("しょ", "SHO"); map.put("ちゃ", "CHA"); map.put("ちゅ", "CHU"); map.put("ちょ", "CHO"); map.put("にゃ", "NYA"); map.put("にゅ", "NYU"); map.put("にょ", "NYO"); map.put("ひゃ", "HYA"); map.put("ひゅ", "HYU"); map.put("ひょ", "HYO"); map.put("みゃ", "MYA"); map.put("みゅ", "MYU"); map.put("みょ", "MYO"); map.put("りゃ", "RYA"); map.put("りゅ", "RYU"); map.put("りょ", "RYO"); map.put("ぎゃ", "GYA"); map.put("ぎゅ", "GYU"); map.put("ぎょ", "GYO"); map.put("じゃ", "JA"); map.put("じゅ", "JU"); map.put("じょ", "JO"); map.put("びゃ", "BYA"); map.put("びゅ", "BYU"); map.put("びょ", "BYO"); map.put("ぴゃ", "PYA"); map.put("ぴゅ", "PYU"); map.put("ぴょ", "PYO"); map.put("ゆう", "YU"); map.put("あ", "A"); map.put("か", "KA"); map.put("さ", "SA"); map.put("た", "TA"); map.put("な", "NA"); map.put("は", "HA"); map.put("ま", "MA"); map.put("や", "YA"); map.put("ら", "RA"); map.put("わ", "WA"); map.put("が", "GA"); map.put("ざ", "ZA"); map.put("だ", "DA"); map.put("ば", "BA"); map.put("ぱ", "PA"); map.put("い", "I"); map.put("き", "KI"); map.put("し", "SHI"); map.put("ち", "CHI"); map.put("に", "NI"); map.put("ひ", "HI"); map.put("み", "MI"); map.put("り", "RI"); map.put("ぎ", "GI"); map.put("じ", "JI"); map.put("ぢ", "JI"); map.put("び", "BI"); map.put("ぴ", "PI"); map.put("う", "U"); map.put("く", "KU"); map.put("す", "SU"); map.put("つ", "TSU"); map.put("ぬ", "NU"); map.put("ふ", "FU"); map.put("む", "MU"); map.put("ゆ", "YU"); map.put("る", "RU"); map.put("を", "O"); map.put("ぐ", "GU"); map.put("ず", "ZU"); map.put("づ", "ZU"); map.put("ぶ", "BU"); map.put("ぷ", "PU"); map.put("え", "E"); map.put("け", "KE"); map.put("せ", "SE"); map.put("て", "TE"); map.put("ね", "NE"); map.put("へ", "HE"); map.put("め", "ME"); map.put("れ", "RE"); map.put("げ", "GE"); map.put("ぜ", "ZE"); map.put("で", "DE"); map.put("べ", "BE"); map.put("ぺ", "PE"); map.put("お", "O"); map.put("こ", "KO"); map.put("そ", "SO"); map.put("と", "TO"); map.put("の", "NO"); map.put("ほ", "HO"); map.put("も", "MO"); map.put("よ", "YO"); map.put("ろ", "RO"); map.put("ん", "N"); map.put("ご", "GO"); map.put("ぞ", "ZO"); map.put("ど", "DO"); map.put("ぼ", "BO"); map.put("ぽ", "PO"); map.put("ー", ""); } static class HData { String s = ""; String h = ""; boolean isPacked = false; } static public String convert(String text) { StringBuilder hebon = new StringBuilder(); int pos = 0; int len = text.length(); String lastConvert = null; loop: while (pos < len) { String c = ""; /* * mapで変換 */ convert: { c2: if (pos + 2 <= len) { c = map.get(text.subSequence(pos, pos + 2)); if (c != null) { pos += 2; break convert; } } c1: if (pos < len) { c = map.get(text.subSequence(pos, pos + 1)); if (c != null) { pos += 1; break convert; } } c_nothing: { c = text.substring(pos, pos + 1); pos += 1; } } /* * その他の規則での置き換え */ convert_another_rule: { // ひつと前の変換が[っ]の場合は if ("xtu".equals(lastConvert) && c.startsWith("CH")) { hebon.append("T"); break convert_another_rule; } if ("xtu".equals(lastConvert)) { hebon.append(c.substring(0, 1)); break convert_another_rule; } if ("N".equals(lastConvert) && (c.matches("[B|M|P].*"))) { hebon.append("M"); break convert_another_rule; } if ("N".equals(lastConvert)) { hebon.append("N"); break convert_another_rule; } } /* * 最後に変換したものと+変換したもので母音がつながる場合は、追加しない */ append: { /* 母音がつながる判定 */ boolean isBoon = (lastConvert + c) .matches(".*(AA|II|UU|EE|OO|OU)$"); if (!isBoon && (!(c.matches("xtu") || c.matches("N")) || !(pos < len))) { hebon.append(c); } /* 母音がつながったら 最後に変換したものの対象外 */ if (isBoon) { lastConvert = ""; continue; } } lastConvert = c; } return hebon.toString(); } } public static void main(String[] args) { a(); } static void a() { String[][] ss = { { "っ", "TSU" }, { "っっ", "TSU" }, { "ああ", "A" }, { "ひらがな", "HIRAGANA" }, { "ひたち", "HITACHI" }, { "ほっち", "HOTCHI" }, { "はっちょう", "HATCHO" }, { "なんば", "NAMBA" }, { "こうの", "KONO" }, { "おおしま", "OSHIMA" }, { "おおの", "ONO" }, { "おの", "ONO" }, { "おお", "O" }, { "はっとり", "HATTORI" }, { "ゆうか", "YUKA" }, { "さんぺい", "SAMPEI" }, { "おおおか", "OOKA" }, { "あ", "A" }, { "ぴょう", "PYO" }, { "かんさいくうこう", "KANSAIKUKO" }, { "ん", "N" }, { "んん", "NN" }, { "べっぷ", "BEPPU" }, { "こっち", "KOTCHI" }, { "じょうお", "JOO" }, { "じょう", "JO" }, { "しろうず", "SHIROZU" }, { "ふ", "FU" }, { "はは や ちち", "HAHA YA CHICHI" }, { "おおおおお", "OOO" } }; for (String[] s : ss) { String c = HebonConvert.convert(s[0]); System.out.println(s[0] + ":変換:[" + c + "] " + (s[1].equals(c) ? "○" : "×")); } } }

: