转换组合diaereses到ISO 8859-1

时间:2014-09-23 21:09:34

标签: java encoding utf-8 iso-8859-1

这类似于this question,但我特别需要知道如何转换为ISO-8859-1格式,而不是UTF-8。

简短的问题:我需要一个将角度转换为拉丁-1等效的角色(如果存在)。

更长的问题:我有德语字符串,包含组合diaereses(UTF-8:[cc] [88] AKA UTF代码点U + 0308),但我的数据库只支持ISO-8859-1(例如Latin-1) 。因为角色/组合的分析是"分解",我不能只是"转换"到ISO-8859-1,因为字节序列[cc] [88]作用于前面的字符,在ISO-8859-1中可能没有相应的字符。

我试过这段代码:

import java.nio.charset.Charset;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;

//ü has combining diaereses
String s = "für"
Charset utf8charset = Charset.forName("UTF-8");
Charset iso88591charset = Charset.forName("ISO-8859-1");

ByteBuffer inputBuffer = ByteBuffer.wrap(s.getBytes());

// decode UTF-8
CharBuffer data = utf8charset.decode(inputBuffer);

// encode ISO-8559-1
ByteBuffer outputBuffer = iso88591charset.encode(data);
byte[] outputData = outputBuffer.array();

isoString = new String(outputData);

//isoString is "fu?r"

但它只是没有编码组合的干扰,而不是看到它可以转换为U + 00F6 / [c3] [bc]。是否有一个库可以检测一个字符,然后组合diaereses可以映射到现有的ISO-8859-1字符? (最好是Java)

2 个答案:

答案 0 :(得分:3)

您需要在编码之前进行标准化。

使用the Normalizer class转换为已分解的表单,然后进行编码。

答案 1 :(得分:1)

对于bmargulies的回答,正常化是关键。

以下是有效的代码:

import java.nio.charset.Charset;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.text.Normalizer;
import java.text.Normalizer.Form;

private static String encodeToLatin1(byte[] input) {
    String encodedString = null;

    Charset utf8charset = Charset.forName("UTF-8");
    Charset latin1 = Charset.forName("ISO-8859-1");

    ByteBuffer inputBuffer = ByteBuffer.wrap(input);
    CharBuffer data = utf8charset.decode(inputBuffer);
    ByteBuffer outputBuffer = latin1.encode(Normalizer.normalize(data, Normalizer.Form.NFC));

    try {
        encodedString = new String(outputBuffer.array(), "ISO-8859-1");
    } catch (UnsupportedEncodingException e) {
        //do stuff    
    }
    return encodedString;
}

//String with a combining diaereses and without
String s = "Lösung für"    

//Returns "Lösung für"
encodeToLatin1(s.getBytes())