背景
業務で、文字列の全角→半角、または半角→全角変換を実装する必要が生じた。調べた結果のメモ。
用途は、比較処理時の表記揺れの吸収。
要件
- 変換対象:英数字,記号
- 記号は、一対一で変換可能なものだけ対象としたい(いわゆる環境依存文字は対象から除外)。
- カタカナについて変換の必要はないが、用途上、一意になるなら変換されても問題ない。
- 実行環境:Java SE 8u201(64bit)
方法
Normalizer
方法1。Java6以降で使用可能なjava.text.Normalizer
を使用する方法。
懸念として、全角⇔半角変換を目的としたものではないため、正規化の過程で余計な変換が生じる可能性がある。
ICU4J
ICU - International Components for Unicode
方法2。外部ライブラリを使用する。
執筆時点での最新バージョンであるICU4J 63.1を使用する。
ソース
Transliterator fullToHalf = Transliterator.getInstance("Fullwidth-Halfwidth");
Transliterator halftoFull = Transliterator.getInstance("Halfwidth-Fullwidth");
String target =
"全半“ ”\" \"あがぱアガパアガパABabABab123123「」()()[][];;!!??##//--・┣①⑪㌀㈱㌔¼⑴";
System.out.println("target :" + target);
System.out.println("NFC :" + Normalizer.normalize(target, Normalizer.Form.NFC));
System.out.println("NFD :" + Normalizer.normalize(target, Normalizer.Form.NFD));
System.out.println("NFKC :" + Normalizer.normalize(target, Normalizer.Form.NFKC));
System.out.println("NFKD :" + Normalizer.normalize(target, Normalizer.Form.NFKD));
System.out.println("ICU4J H:" + fullToHalf.transliterate(target));
System.out.println("ICU4J F:" + halftoFull.transliterate(target));
実行結果
target :全半“ ”" "あがぱアガパアガパABabABab123123「」()()[][];;!!??##//--・┣①⑪㌀㈱㌔¼⑴
NFC :全半“ ”" "あがぱアガパアガパABabABab123123「」()()[][];;!!??##//--・┣①⑪㌀㈱㌔¼⑴
NFD :全半“ ”" "あがぱアガパアガパABabABab123123「」()()[][];;!!??##//--・┣①⑪㌀㈱㌔¼⑴
NFKC :全半“ ”" "あがぱアガパアガパABabABab123123「」()()[][];;!!??##//--・┣111アパート(株)キロ1⁄4(1)
NFKD :全半“ ”" "あがぱアガパアガパABabABab123123「」()()[][];;!!??##//--・┣111アパート(株)キロ1⁄4(1)
ICU4J H:全半“ ”" "あがぱアガパアガパABabABab123123「」()()[][];;!!??##//--・┣①⑪㌀㈱㌔¼⑴
ICU4J F:全半“ ”" "あがぱアガパアガパABabABab123123「」()()[][];;!!??##//--・┣①⑪㌀㈱㌔¼⑴
結論
今回はICU4Jで全角→半角変換する方法に決めました。
事前に入力を絞れるのであれば、Normalizerの方がお手軽で良いと思います。