2014-09-23 25 views
2

這與this question類似,但我特別需要知道如何轉換爲ISO-8859-1格式,而不是UTF-8。將組合字符集轉換爲ISO 8859-1

簡短的問題:我需要一個字符結合diaereses轉換爲拉丁-1相當(如果存在)。 (UTF-8:[cc] [88]和另一個UTF代碼點U + 0308),但我的數據庫只支持ISO-8859-1(例如Latin-1 )。由於字符/合併字段是「分解」的,因爲字節序列[cc] [88]作用於前面的字符,因此我不能將其轉換爲ISO-8859-1,因爲前面的字符可能沒有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" 

,但它只是不能編碼合成diaereses,而不是看到,它可以轉換爲U + 00F6/[C3] [BC]。有沒有一個庫可以檢測到一個字符後跟組合的字符串可以映射到現有的ISO-8859-1字符? (最好用Java)

回答

3

你需要在編碼之前進行歸一化處理。

使用the Normalizer class轉換爲分解形式,然後編碼。

+0

Upvoted造成的。我將發佈我的例子作爲更明確示例的另一個答案。 – Devin 2014-09-23 23:52:17

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()) 
相關問題