Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all articles
Browse latest Browse all 11804

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

$
0
0

转:

[JDK自带了native2ascii,但是很多时候还是需要自己写程序去解析unicode编码问题,网上的decodeUnicode
这个方法实现有比较严重的解析问题实在是个大坑,转了作者的这篇文章希望大家不要再用decodeUnicode了,
还有就是使用别人代码之前毋必仔细尝试!]
原文:http://448230305.iteye.com/blog/2159336

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

Java转unicode转中文的情况使用的场景很多,是一个很常见的需求,按理来说,这样的功能应该被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);
}

输出:

香煎马鲛鱼的博客

可是像上面那种情况在实际问题里是很少见的,在1例子中,”\”是转义字符,实际我们得到的unicode编码是这样的:

public static void main(String[] args){
     String string= "\\u9999\\u714e\\u9a6c\\u9c9b\\u9c7c\\u7684\\u535a\\u5ba2";
     System.out.println(string);
}

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

\u9999\u714e\u9a6c\u9c9b\u9c7c\u7684\u535a\u5ba2

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

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

\u9999\\u714e\u9c7c香\u714e鱼香\煎鱼转义有误

测试项例子输出正确结果总结
基本能力\u9999\u714e\u9c7c香煎鱼香煎鱼正确
中英文数字混合1\u9999123\u714ehi\u9c7ca1香123煎hi鱼a1香123煎hi鱼a正确
中英文,特殊字符混合\u9999\u\u714e\u9c7c(错误)香\u煎鱼无法正常运行

可见,方法一虽然能对中英混合进行识别,但对\和\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(错误)1香123煎hi鱼a无法正常运行
中英文,特殊字符混合\u9999\u\u714e\u9c7c(错误)香\u煎鱼无法正常运行
\u9999\\u714e\u9c7c(错误)香\u煎鱼无法正常运行

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

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\u9c7ca1香123煎hi鱼a1香123煎hi鱼a正确
中英文,特殊字符混合\u9999\u\u714e\u9c7c香\u煎鱼香\u煎鱼正确
\u9999\\u714e\u9c7c香\煎鱼香\u煎鱼正确

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

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;
}

Viewing all articles
Browse latest Browse all 11804

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>