2014-09-23 5 views
2

이것은 this question과 유사하지만 특히 UTF-8이 아닌 ISO-8859-1 형식으로 변환하는 방법을 알아야합니다.결합 분음을 ISO 8859-1로 변환

간단한 질문 : 나는 (만약 존재한다면) 라틴 -1 동등 물로 변환 된 디아 메르가있는 캐릭터가 필요합니다.

더 긴 질문 : 나는 결합 분 지형 (UTF-8 : [cc] [88] 일명 UTF 코드 포인트 U + 0308)을 포함하는 독일어 문자열을 가지고 있지만 데이터베이스는 ISO-8859-1 (예 : Latin-). 문자/결합 디아 예가 "분해"되기 때문에 바이트 시퀀스 [cc] [88]가 ISO에서 해당 문자를 갖지 않을 수있는 선행 문자에서 작동하기 때문에 ISO-8859-1로 "변환"할 수 없습니다 -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 문자에 지형을 결합한 문자가 언제 매핑 될 수 있는지를 감지 할 수있는 라이브러리가 있습니까? (선호 자바 있음)

답변

3

인코딩하기 전에 정규화해야합니다.

the Normalizer class을 사용하면 분해 된 양식으로 변환 한 다음 인코딩 할 수 있습니다.

+0

Upvoted, 원인 일 : 여기

일했다 코드입니다. 내 예를 좀 더 명확한 예를 들어 다른 답으로 게시 할 것입니다. – Devin

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())