Java的Unicode编码转化(多种景况处理方法)

Java的Unicode编码转化(多种情况处理方法)

JavaUnicode编码转化(多种情况处理方法)

Javaunicode转中文的情况使用的场景很多,是一个很常见的需求,按理来说,这样的功能应该被java集成起来,不过很遗憾,java提供的方法很烂,很多时候我们需要自己去写。

好在这个需求的源代码网上很多,在查资料的过程中,我找到啦好几种,下面我将我找到的资料分享和我自己实现的方法提供给大家;希望大家能有个参考;

1、java中使用的是unicode编码,所以如果我们得到的本身就是一个unicode编码,那么我们可以直接print出来的就是中文:

    public static void main(String[] args){

        String string= "\u9999\u714e\u9a6c\u9c9b\u9c7c\u7684\u535a\u5ba2";

        System.out.println(string);

    }

 

输出:

 


Java的Unicode编码转化(多种景况处理方法)
 可是像上面那种情况在实际问题里是很少见的,在1例子中,
\是转义字符,实际我们得到的unicode编码是这样的:

    public static void main(String[] args){

        String string= "\\u9999\\u714e\\u9a6c\\u9c9b\\u9c7c\\u7684\\u535a\\u5ba2";

        System.out.println(string);

    }

而这样得到的输出结果就变成了这样:

 


Java的Unicode编码转化(多种景况处理方法)
 

这样的结果肯定是我们不想要的,那么解决方法是什么呢:

方法一:这是在网上最常见的一种方法,直接将方法decodeUnicode放在类中就可以,方便,不过缺点就是代码量比较大,下面我们测试一下它的转义能力

测试项

例子

输出

正确结果

总结

基本能力

\u9999\u714e\u9c7c

香煎鱼

香煎鱼

正确

中英文数字混合

1\u9999123\u714ehi\u9c7ca

1123hia

1123hia

正确

中英文,特殊字符混合

\u9999\u\u714e\u9c7c

(错误)

\u煎鱼

无法正常运行

\u9999\\u714e\u9c7c

\u714e

\煎鱼

转义有误

可见,方法一虽然能对中英混合进行识别,但对\\u的识别仍然存在问题,我们可以给他打70分;

    public static String decodeUnicode(String theString) {

        char aChar;

        int len = theString.length();

        StringBuffer outBuffer = new StringBuffer(len);

        for (int x = 0; x < len;) {

            aChar = theString.charAt(x++);

            if (aChar == '\\') {

                aChar = theString.charAt(x++);

                if (aChar == 'u') {

                    // Read the xxxx

                    int value = 0;

                    for (int i = 0; i < 4; i++) {

                        aChar = theString.charAt(x++);

                        switch (aChar) {

                            case '0':

                            case '1':

                            case '2':

                            case '3':

                            case '4':

                            case '5':

                            case '6':

                            case '7':

                            case '8':

                            case '9':

                                value = (value << 4) + aChar - '0';

                                break;

                            case 'a':

                            case 'b':

                            case 'c':

                            case 'd':

                            case 'e':

                            case 'f':

                                value = (value << 4) + 10 + aChar - 'a';

                                break;

                            case 'A':

                            case 'B':

                            case 'C':

                            case 'D':

                            case 'E':

                            case 'F':

                                value = (value << 4) + 10 + aChar - 'A';

                                break;

                            default:

                                throw new IllegalArgumentException(

                                        "Malformed   \\uxxxx   encoding.");

                        }

                    }

                    outBuffer.append((char) value);

                } else {

                    if (aChar == 't')

                        aChar = '\t';

                    else if (aChar == 'r')

                        aChar = '\r';

                    else if (aChar == 'n')

                        aChar = '\n';

                    else if (aChar == 'f')

                        aChar = '\f';

                    outBuffer.append(aChar);

                }

            } else

                outBuffer.append(aChar);

        }

        return outBuffer.toString();

    }

}

 

方法二:此种方法在网上也比较常见,代码量少,可读性强是它最大的优点,但是,它的转义能力……大家自己体会一下吧;

测试项

例子

输出

正确结果

总结

基本能力

\u9999\u714e\u9c7c

香煎鱼

香煎鱼

正确

中英文数字混合

1\u9999123\u714ehi\u9c7ca

(错误)

1123hia

无法正常运行

中英文,特殊字符混合

\u9999\u\u714e\u9c7c

(错误)

\u煎鱼

无法正常运行

\u9999\\u714e\u9c7c

(错误)

\煎鱼

无法正常运行

它的转义能力决定它的实用性不强,但是鉴于它比较简单,所以还是有一定市场的,不过也请大家谨慎使用,根据我的测试,这种转码方式只对全中文有效

    public static String ascii2native_orl(String ascii) {

        int n = ascii.length() / 6;

        StringBuilder sb = new StringBuilder(n);

        for (int i = 0, j = 2; i < n; i++, j += 6) {

            String code = ascii.substring(j, j + 4);

            char ch = (char) Integer.parseInt(code, 16);

            sb.append(ch);

        }

        return sb.toString();

}

 

方法三:既然方法二有问题,那么我们能不能对他进行一些改进,让它适应性更强呢,当然,如果方法二加上正则表达式,就有更强的功能了

测试项

例子

输出

正确结果

总结

基本能力

\u9999\u714e\u9c7c

香煎鱼

香煎鱼

正确

中英文数字混合

1\u9999123\u714ehi\u9c7ca

1123hia

1123hia

正确

中英文,特殊字符混合

\u9999\u\u714e\u9c7c

\u煎鱼

\u煎鱼

正确

\u9999\\u714e\u9c7c

\煎鱼

\煎鱼

正确

   这种方法很好利用了正则表达式,代码可读性强,转义能力也很不错,强烈推荐

 public static String ascii2native(String ascii) {

 

        List<String> ascii_s = new ArrayList<String>();

        String zhengz= "\\\\u[0-9,a-f,A-F]{4}";

        Pattern p = Pattern.compile(zhengz);

        Matcher m=p.matcher(ascii);

        while (m.find()){

            ascii_s.add(m.group());

        }

        for (int i = 0, j = 2; i < ascii_s.size(); i++) {

            String code = ascii_s.get(i).substring(j, j + 4);

            char ch = (char) Integer.parseInt(code, 16);

            ascii = ascii.replace(ascii_s.get(i),String.valueOf(ch));

        }

        return ascii;

}

 

总结:其实,三种方法的基本思想都是一样的,但是最大的区别就是在怎么短句,短句的方法不同,解析能力也不同。

<!--EndFragment-->
1 楼 ahack 2 小时前  
多谢楼主分享,decodeUnicode的代码的确有问题。