Javaの文字セット間で文字の音訳を実現する方法はありますか?unixコマンド(または同様のphp関数)に似たもの:
iconv -f UTF-8 -t ASCII//TRANSLIT < some_doc.txt > new_doc.txt
できれば文字列を操作し、ファイルとは何の関係もありません
コンストラクターを使用してエンコードを変更できることは知っていますがString
、結果の文字セットに含まれていない文字の音訳は処理されません。
私は、iconv
(あまり明確に定義されていないように思われる)意図したことを正確に実行するライブラリを知りません。ただし、 Javaの「正規化」を使用して、文字からアクセントを削除するなどの操作を行うことができます。このプロセスは、Unicode標準によって明確に定義されています。
NFKD(互換性分解)とそれに続く非ASCII文字のフィルタリングにより、目的に近づく可能性があると思います。明らかに、これは損失の多いプロセスです。元の文字列に含まれていたすべての情報を復元することはできないため、注意してください。
/* Decompose original "accented" string to basic characters. */
String decomposed = Normalizer.normalize(accented, Normalizer.Form.NFKD);
/* Build a new String with only ASCII characters. */
StringBuilder buf = new StringBuilder();
for (int idx = 0; idx < decomposed.length(); ++idx) {
char ch = decomposed.charAt(idx);
if (ch < 128)
buf.append(ch);
}
String filtered = buf.toString();
ここで使用するフィルタリングを使用すると、一部の文字列が読み取れなくなる可能性があります。たとえば、漢字の文字列はASCII表現を持たないため、完全に除外されます(これはiconvに似ています//IGNORE
)。
全体として、有効な文字置換の独自のルックアップテーブルを作成するか、少なくとも削除しても安全な文字(アクセントと物)を組み合わせる方が安全です。最善の解決策は、処理する予定の入力文字の範囲によって異なります。
1つの解決策は、executeiconvを外部プロセスとして実行することです。それは確かに純粋主義者を怒らせるでしょう。それはシステム上のiconvの存在に依存しますが、それは機能し、あなたが望むことを正確に実行します:
public static String utfToAscii(String input) throws IOException {
Process p = Runtime.getRuntime().exec("iconv -f UTF-8 -t ASCII//TRANSLIT");
BufferedWriter bwo = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));
bwo.write(input,0,input.length());
bwo.flush();
bwo.close();
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
while( ( line = bri.readLine() ) != null ) {
stringBuilder.append( line );
stringBuilder.append( ls );
}
bri.close();
try {
p.waitFor();
} catch ( InterruptedException e ) {
}
return stringBuilder.toString();
}