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

标签: Java | 发表时间:2014-11-23 15:23 | 作者:转载
出处:http://javaweb.org

转:

[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\u9c7ca 1香123煎hi鱼a 1香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\u9c7ca 1香123煎hi鱼a 1香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;
}

相关 [java unicode 编码] 推荐:

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

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

中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030

- - 博客园_学院派的驴
转自: http://hi.baidu.com/okptqdwpfrbosuq/item/0fc063f8b65f0516d6ff8c03. 中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030. 转自: http://www.blog.edu.cn/user3/flyingcs/archives/2006/1418577.shtml 概要:UTF-8的一个特别的好处是它与ISO- 8859-1完全兼容,可以表示世界上所有的字符,汉字通常用3个字节来表示.

字符编码笔记:ASCII,Unicode和UTF-8

- - 移动开发 - ITeye博客
今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问题比我想象的复杂,从午饭后一直看到晚上9点,才算初步搞清楚. 下面就是我的笔记,主要用来整理自己的思路. 但是,我尽量试图写得通俗易懂,希望能对其他朋友有用. 毕竟,字符编码是计算机技术的基石,想要熟练使用计算机,就必须懂得一点字符编码的知识.

java编码规范

- - ITeye博客
   总结前期做的几个项目,个人认为代码的规范对团队的协作有着密切的关系. 现将一些常用的约束总结如下,以便今后参阅:. 1、所有的类、属性、方法都遵守以字母和数字为主,尽量不要参与特殊符号如下划线. 其次,除类名开头字母大写外,其他名字都要小写,然后第二个后的单词首字母大写,长度在30个字符以内.

Java/Android编码规范

- - CSDN博客推荐文章
1.        为什么需要编码规范?. 编码规范对于程序员而言尤为重要,有以下几个原因:. l        一个软件的生命周期中,80%的花费在于维护. l        几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护. l        编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码.

Java写xml文件的编码问题

- - CSDN博客推荐文章
最近项目中需要生成xml格式的配置文件,用的是 javax.xml.transform.Transformer 类中提供的transform方法,在本地执行没问题,但是一旦把工程部署到Tomcat下运行,就会出现中文乱码的现象,纠结了许久,在大神的帮助下终于解决了. 有篇文章其实已经讲的很清楚了,链接如下:.

Java编码规范(Google版本)

- - 研发管理 - ITeye博客
本文摘自:http://hawstein.com/posts/google-java-style.html. 这份文档是Google Java编程风格规范的完整定义. 当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合Google的Java编程风格. 与其它的编程风格指南一样,这里所讨论的不仅仅是编码格式美不美观的问题,同时也讨论一些约定及编码标准.

java编码规范及优化总结

- - CSDN博客编程语言推荐文章
1991 年Sun公司的James Gosling(詹姆斯·高斯林)等人开始开发名称为 Oak 的语言,希望用于控制嵌入在有线电视交换盒、PDA等的微处理器. 1994年将Oak语言更名为Java. 二、 Java的三种技术架构. J2EE:Java PlatformEnterprise Edition,开发企业环境下的应用程序,主要针对web程序开发;.

深入分析 Java 中的中文编码问题

- Alex - IBM developerWorks 中国 : 文档库
编码问题一直困扰着开发人员,尤其在 Java 中更加明显,因为 Java 是跨平台语言,不同平台之间编码之间的切换较多. 本文将向你详细介绍 Java 中编码问题出现的根本原因,你将了解到:Java 中经常遇到的几种编码格式的区别;Java 中经常需要编码的场景;出现中文问题的原因分析;在开发 Java web 程序时可能会存在编码的几个地方,一个 HTTP 请求怎么控制编码格式.

[Java] Proxy在实际编码中的应用

- - ITeye博客
Java的类反射机制中包括了动态代理技术,其核心设计围绕InvocationHandler接口和Proxy类. 我们定义一个Car接口,然后实现它:. 一般情况下,我们可以这样使用它:. 如果我们要用Proxy来做,首先需要一个实现了InvocationHandler的代理类:. 执行程序,同样会输出BigCar.