ヘボン式変換 たたき台 - java
2014/01/08
2014/01/18
java
ヘボン式
追記リリースしました!
「文章」を「ヘボン式ローマ字」に変換ツール(β)
前回、プログラマメモ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) ? "○" : "×"));
}
}
}
: