在java中是否有带有//TRANSLIT等效物的图标?

2022-09-03 13:47:54

有没有办法在java中实现字符集之间的字符音译?类似于 unix 命令(或类似的 php 函数):

iconv -f UTF-8 -t ASCII//TRANSLIT < some_doc.txt  > new_doc.txt

最好对字符串进行操作,与文件无关

我知道您可以使用构造函数更改编码,但这不能处理不在结果字符集中的字符的音译。String


答案 1

我不知道有任何库可以完全做所谓的事情(这似乎不是很明确)。但是,您可以在Java中使用“规范化”来执行诸如从字符中删除重音符号之类的操作。此过程由 Unicode 标准很好地定义。iconv

我认为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

总体而言,构建自己的有效字符替换查找表,或者至少组合可以安全剥离的字符(重音符号和事物)会更安全。最佳解决方案取决于您希望处理的输入字符的范围。


答案 2

一种解决方案是将执行 iconv 作为外部进程执行。它肯定会冒犯纯粹主义者。这取决于系统上 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();
}

推荐