全角と半角、ひらがなとカタカナ、さらにはローマ字表記との相互変換まで、ICU4Jを使うと簡単に変換処理を実装することができます。さらに、変換ルールを設計すればある程度複雑な変換もできるようになります。本稿では、文字変換に便利なライブラリICU4JのTransliteratorについて解説します。
- ひらがな⇔カタカナ、ローマ字⇔ひらがな、ローマ字⇔カタカナの変換を簡単に行いたい
- 文字列検索のためのノーマライズとして全角→半角の変換を簡単に行いたい
ICU4Jとは
ICU4J (International Components for Unicode for Java) はオープンソースの Java ライブラリのセットで、導入するアプリケーションのグローバル化をサポートしており、日本語の他、ロシア語やギリシャ語などの様々な言語に対応しています。
その中でも主要なクラスであるTransliteratorは、日本語であればひらがなからカタカナへの変換やローマ字への変換、全角から半角への変換など、様々な文字変換を行うことができます。
ICUに現在、C版とJava版が公開されていますが、ここではJava版の使用方法についてサンプルを紹介します。
セットアップ
ICU4Jは公式HP ICU – International Components for Unicode よりダウンロードすることができます。
2019年9月の時点で最新バージョンは64.2です。今回直接の関係はありませんが、令和への対応が盛り込まれるなど常に更新されています。なるべく最新のバージョンを使用することをおすすめします。
Mavenを使用する場合は、pom.xmlに以下の定義を追加してください。
<!-- https://mvnrepository.com/artifact/com.ibm.icu/icu4j -->
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>64.2</version>
</dependency>
サンプルソース
基本的な使い方としては、Transliterator のインスタンスを取得する際に指定するidによって、transliterate() で処理する内容が変わります。
全角→半角 変換
IDに”Fullwidth-Halfwidth”を指定します。半角変換できない場合は未変換のままになります。
ソース
Transliterator trans = Transliterator.getInstance("Fullwidth-Halfwidth");
String zenkaku = "デベルマン でべるまん Develman.net123";
String hankaku = trans.transliterate(zenkaku);
System.out.println("変換前(全角):" + zenkaku);
System.out.println("変換前(半角):" + hankaku);
実行結果
変換前(全角):デベルマン でべるまん Develman.net123 変換前(半角):デベルマン でべるまん Develman.net123
半角→全角 変換
IDに”Halfwidth-Fullwidth”を指定します。
ソース
Transliterator trans = Transliterator.getInstance("Halfwidth-Fullwidth");
String hankaku = "デベルマン Develman.net123";
String zenkaku = trans.transliterate(hankaku);
System.out.println("変換前(半角):" + hankaku);
System.out.println("変換前(全角):" + zenkaku);
実行結果
変換前(半角):デベルマン Develman.net123 変換前(全角):デベルマン Develman.net123
ひらがな→カタカナ 変換
IDに”Hiragana-Katakana”を指定します。
ソース
Transliterator trans = Transliterator.getInstance("Hiragana-Katakana");
String hiragana = "でべるまん";
String katakana = trans.transliterate(hiragana);
System.out.println("変換前(ひらがな):" + hiragana);
System.out.println("変換前(カタカナ):" + katakana);
実行結果
変換前(ひらがな):でべるまん 変換前(カタカナ):デベルマン
カタカナ→ひらがな 変換
IDに”Katakana-Hiragana”を指定します。半角もそのまま全角ひらがなに変換されます。
ソース
Transliterator trans = Transliterator.getInstance("Katakana-Hiragana");
String katakana = "デベルマン デベルマン";
String hiragana = trans.transliterate(katakana);
System.out.println("変換前(カタカナ):" + katakana);
System.out.println("変換前(ひらがな):" + hiragana);
実行結果
変換前(カタカナ):デベルマン デベルマン 変換前(ひらがな):でべるまん でべるまん
ローマ字→ひらがな 変換
IDに”Latin-Hiragana”を指定します。多少無理のある変換なのでひらがな⇔ローマ字では可逆的に変換できないことがあります。
ソース
Transliterator trans = Transliterator.getInstance("Latin-Hiragana");
String latin = "Develman";
String hiragana = trans.transliterate(latin);
System.out.println("変換前(英字) :" + latin);
System.out.println("変換前(ひらがな):" + hiragana);
実行結果
変換前(英字) :Develman 変換前(ひらがな):でゑ゙るまん //ゑ゙て..
ひらがな→ローマ字 変換
IDに”Hiragana-Latin”を指定します。
ソース
Transliterator trans = Transliterator.getInstance("Hiragana-Latin");
String hiragana = "でゑ゙るまん";
String latin = trans.transliterate(hiragana);
System.out.println("変換前(ひらがな):" + hiragana);
System.out.println("変換前(英字) :" + latin);
実行結果
変換前(ひらがな):でゑ゙るまん 変換前(英字) :deveruman
文字削除
IDに”Any-Remove”を指定します。
ソース
Transliterator trans = Transliterator.getInstance("Any-Remove");
String src = "develman";
String dst = trans.transliterate(src);
System.out.println("変換前:" + src);
System.out.println("変換前:" + dst);
実行結果
変換前:develman 変換前:
“Any-Remove”単体ではあまり使い道はありませんが、フィルタと一緒に使用することで使い道に幅が出てきます。
ソース
Transliterator trans = Transliterator.getInstance("[:Lower:] Any-Remove");
String src = "Develman";
String dst = trans.transliterate(src);
System.out.println("変換前:" + src);
System.out.println("変換前:" + dst);
実行結果
変換前:Develman 変換前:D
大文字変換
IDに”Any-Upper”を指定します。大文字変換は java.lang.String で事足りるため、”Any-Remove”と同様にフィルタと一緒に使用する使い道が一般的です。
ソース
Transliterator trans = Transliterator.getInstance("Any-Upper");
String src = "develman";
String dst = trans.transliterate(src);
System.out.println("変換前:" + src);
System.out.println("変換前:" + dst);
実行結果
変換前:develman 変換前:DEVELMAN
小文字変換
IDに”Any-Lower”を指定します。小文字変換は java.lang.String で事足りるため、”Any-Remove”と同様にフィルタと一緒に使用する使い道が一般的です。
ソース
Transliterator trans = Transliterator.getInstance("Any-Lower");
String src = "DEVELMAN";
String dst = trans.transliterate(src);
System.out.println("変換前:" + src);
System.out.println("変換前:" + dst);
実行結果
変換前:DEVELMAN 変換前:develman
先頭を大文字に変換
IDに”Any-Title”を指定します。単語の先頭を大文字にします。
ソース
Transliterator trans = Transliterator.getInstance("Any-Title");
String src = "develman, written by sasakiyu";
String dst = trans.transliterate(src);
System.out.println("変換前:" + src);
System.out.println("変換前:" + dst);
実行結果
変換前:develman, written by sasakiyu 変換前:Develman, Written By Sasakiyu
複雑な条件の文字変換
例)特定の位置の文字を変換する
位置を指定することで特定の文字のみ変換対象とすることができます。
ソース
Transliterator transHiragana = Transliterator.getInstance("Latin-Hiragana");
Transliterator transKatakana = Transliterator.getInstance("Latin-Katakana");
Replaceable r = new ReplaceableString("Doraemon");
System.out.println("変換前:" + r.toString());
transHiragana.transliterate(r, 4, 8);
transKatakana.transliterate(r, 0, 4);
System.out.println("変換前:" + r.toString());
実行結果
変換前:Doraemon 変換前:ドラえもん
例)濁点を取り除く
複数の処理を左から順次実行することができます。
この例では、濁点ありの文字列を一度NFDに変換に変換することで、合成済文字「デ(U+30C7)」を結合文字列「テ(U+30C6)」 「濁点(U+3099)」 に分け、濁点を削除してNFCに戻すことで濁点なしに変換しています。
ソース
Transliterator trans = Transliterator.getInstance(
"NFD; [:Nonspacing Mark:] Remove; NFC;");
String src = "デベルマン";
String dst = trans.transliterate(src);
System.out.println("変換前:" + src);
System.out.println("変換前:" + dst);
実行結果
変換前:デベルマン 変換前:テヘルマン
例)スネークケース→ケバブケース 変換
Transliterator.createFromRules()
で変換のルールを定義できます。この例では、アンダースコアをハイフンに置換し、文字列を小文字に変換しています。
ソース
Transliterator trans = Transliterator.createFromRules("",
"'_' > '-'; :: Lower;",
Transliterator.FORWARD);
String src = "DEVEL_MAN";
String dst = trans.transliterate(src);
System.out.println("変換前:" + src);
System.out.println("変換前:" + dst);
実行結果
変換前:DEVEL_MAN 変換前:devel-man
例)スネークケース→キャメルケース 変換
Transliterator.createFromRules()
で変換のルールを定義できます。この例では、文字列を小文字に変換した後、アンダースコアに続く文字のみ大文字に変換し、アンダースコアを削除しています。
“::Null”自体に特別な効果はありませんが、直前までのルールを適用した段階で::Null以降のルールが適用されるため、この例では::Nullがない場合は想定通り変換できません。
ソース
Transliterator trans = Transliterator.createFromRules("",
":: Lower; '_' { ([:Latin:]) > &Any-Upper($1); :: Null; '_' > ;",
Transliterator.FORWARD);
String src = "DEVEL_MAN_WRITTERN_BY_SASAKIYU";
String dst = trans.transliterate(src);
System.out.println("変換前:" + src);
System.out.println("変換前:" + dst);
実行結果
変換前:DEVEL_MAN_WRITTERN_BY_SASAKIYU 変換前:develManWritternBySasakiyu
その他の変換
ローマ字からひらがなの変換には”Latin-Hiragana”を指定しましたが、”Latin-Hangul”や”Latin-Arabic” などここに紹介していない言語変換や、フィルタ、変換ルールがあります。
複雑な変換ルールを適用した場合は、General Transformsを参照してください。