Java-从unicode转换为ANSI

时间:2011-10-30 07:31:40

标签: java unicode ansi

我有一个字符串\u0986\u09AE\u09BF \u0995\u09BF\u0982\u09AC\u09A6\u09A8\u09CD\u09A4\u09BF\u09B0 \u0995\u09A5\u09BE \u09AC\u09B2\u099B\u09BF。  我需要在ANSI格式的Avwg wKsewš-i K_v ejwQ`中转换它。如何在java中将此Unicode转换为ANSI字符。

编辑:

resultView.setTypeface(typeFace);
String str=new String("\u0986\u09AE\u09BF \u0995\u09BF\u0982\u09AC\u09A6\u09A8\u09CD\u09A4\u09BF\u09B0 \u0995\u09A5\u09BE \u09AC\u09B2\u099B\u09BF");               
resultView.setText(str);

3 个答案:

答案 0 :(得分:6)

  

我需要将其转换为ANSI格式的AvwgwKsewš—i K_v ejwQ

那不是ANSI格式。 Windows中的(误导性命名的)“ANSI”代码页都基于ASCII,在高字节中添加了不同的字符。字节0x41(A)作为ANSI代码页中的前导字母始终表示拉丁语A而非孟加拉语

我认为你有一个自定义符号字体,它将任意符号映射到完全不相关的代码点。每个这样的字体都有自己的可视编码;要在Unicode和自定义视觉编码之间进行转换,您必须通过查看每个字符的字形并将它们与表示相同字母的Unicode字符相匹配来构建您自己的转换表。

我强烈建议您获取支持孟加拉语的正确的Unicode感知字体。陷入任意字体特定编码的内容很难处理(因为从语义上来说,你真正处理的是一个字符串,意思是“AvwgwKsewš-i K_v ejwQ”,其中包含所有编辑和改变案例的问题。

在Windows具有良好的Unicode(甚至ISCII)支持之前,可视编码字体是一个不愉快的遗物。它们今天不应该用于任何事情。

答案 1 :(得分:1)

我不确定你究竟在问什么,但我会假设你问的是如何将一些字符从Unicode转换为8位字符集。 (例如ISO-8859-1是“西欧”语言的字符集,如英语)。

我不知道有什么方法可以自动检测相关的8位字符集,所以我查找了你的一个字符(在这里http://unicode.org/charts/),我可以看到这些字符是孟加拉语。

认为孟加拉语的等效8位字符集称为 x-iscii-be 我的系统上没有安装此功能,因此无法成功完成转换。

编辑:Java不支持charset x-iscii-be,但为了便于说明,我将留下本答案的其余部分。有关支持的字符集列表,请参阅http://download.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html

EDIT2:Android肯定不保证支持这个charset(它保证唯一的8位字符集是ISO-8859-1)。请参阅:http://developer.android.com/reference/java/nio/charset/Charset.html

* 所以,我认为你应该在孟加拉语Android设备上运行一些Charset检测代码 - 也许它支持这个charset。您需要的一切都在我的代码示例中。 *

为了让Java在不同的字符集中转换您的数据,您在Java中需要做的就是检查是否安装了所需的Charset,然后在将String转换为字节时指定所需的Charset。

转换本身非常简单:

    str.getBytes("x-iscii-be");

因此,您可以看到,String本身以一种“规范化”形式(即defaultCharset)存储,您可以将getBytes(charsetName)视为String的“替代输出格式”。 抱歉 - 解释不好!

在您的情况下,也许您只需要将一个Charset分配给resultView,该框架将为您的魔力发挥作用......

以下是我用一些测试代码来说明这一点,并检查系统是否支持给定的字符集。

我有这个代码将字节数组输出为'hex'字符串,这样你就可以看到转换后的数据不同了。

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.Map.Entry;
import java.util.SortedMap;

public class UnicodeTest {
    public static void main(String[] args) throws UnsupportedEncodingException {
        testWestern();
        testBengali();
    }

    public static void testWestern() throws UnsupportedEncodingException {
        String unicodeStr= "\u00c2"; //This is a capital A with an accent.;
        String charsetName= "ISO-8859-1";
        System.out.println("Input (outputted as default charset - normally unicode): "+unicodeStr);
        attempt8bitCharsetConversion(unicodeStr, charsetName);
    }

    public static void testBengali() throws UnsupportedEncodingException {
        String unicodeStr = "\u0986\u09AE\u09BF \u0995\u09BF\u0982\u09AC\u09A6\u09A8\u09CD\u09A4\u09BF\u09B0 \u0995\u09A5\u09BE \u09AC\u09B2\u099B\u09BF";
        String charsetName= "x-iscii-be";
        System.out.println(unicodeStr);
        attempt8bitCharsetConversion(unicodeStr, charsetName);
    }

    public static void attempt8bitCharsetConversion(String input, String charsetName) throws UnsupportedEncodingException {
        SortedMap<String, Charset> availableCharsets = Charset
                .availableCharsets();
        for (Entry<String, Charset> entry : availableCharsets.entrySet()) {
            if (charsetName.equalsIgnoreCase(entry.getKey())) {
                System.out.println("HEXED input : "+ toHex(input.getBytes(Charset.defaultCharset().name())));
                System.out.println("HEXED output: "+ toHex(input.getBytes(entry.getKey())));
            }
        }
        throw new UnsupportedEncodingException(charsetName+ " is not supported on this system");
    }

    public static String toHex(byte[] input) throws UnsupportedEncodingException {
        return String.format("%x", new BigInteger(input));
    }
}

有关字符集转换的更多信息,请参见此处:http://download.oracle.com/javase/tutorial/i18n/text/string.html

字符是一项棘手的业务,所以请原谅我错综复杂的答案。

HTH

答案 2 :(得分:0)

我写过一个可以解决09CBো,09CCৌ,09C7ে,09C8ৈ,09 BFি্য,্র,ৃ在UTF-8中的问题的课程,我通过编辑字体字形来重塑它,你不要需要将其更改为扩展的ASCII,:(但我仍然无法解决你的孟加拉语共轭。为了正确的渲染它需要Android 3.5或更高,它将在Android 4.0(冰淇淋三明治)上顺利工作。