#Unicode #编码方式
之前请求接口返回的 xml 格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<queryWorkOrderResponse xmlns="http://service.olt.lcbmi.lcims.asiainfo.com">
<queryWorkOrderReturn>
<?xml version="1.0" encoding="UTF-8"?><response><status><code>1002</code><msg>请求参数格式错误:查询周期必须距离当前日期180天内</msg></status></response>
</queryWorkOrderReturn>
</queryWorkOrderResponse>
</soapenv:Body><
/soapenv:Envelope>
其中,除了 > 、<、 ",转换成了对应的< > " 之外,出现了包含请 这种 Html entities 格式的字符串。这种不算是正常编码,但可以转换成 Unicode 编码,进而转换成中文。
public static void main (String[] args) throws IOException, DocumentException {
// 定义正则表达式来搜索中文字符的转义符号
Pattern compile = Pattern.compile ("&#.*?;");
// 测试用中文字符
String sourceString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response><status><code>1002</code><msg>请 ;求 ;参 ;数 ;格式错误:查询周期必须距离当前日期 180天内</msg></status></response>\n";
Matcher matcher = compile.matcher (sourceString);
// 循环搜索并转换替换
while (matcher.find ()) {
String group = matcher.group ();
// 获得 16 进制的码 将 请 去掉 &#x ; 然后加上 0 转换成 USC-2方式 0x8BF7,或者
//0x 位数不够就补 0
String hexcode = "0" + group.replaceAll (" (&#|;)", "");
// 字符串形式的 16 进制码转成 int 并转成 char 并替换到源串中
// 通过Integer.decode(String code).intValue()方法获取 十进制数,然后转换成char类型就是中文
sourceString = sourceString.replaceAll (group, (char) Integer.decode (hexcode). intValue () + "");
}
System.out.println (sourceString);
}
又有一次请求接口返回 xml 如下:
{"code": 200, "msg": "Successful!",
"REQUEST_NUM": ["1267554169", "1267554184"],
"COMPLAIN_CONTENT": ["\u63a5\u89e6\u6d41\u6c34\u53f7\uff1a2022022819322481212599492,\u7535\u8bdd\u53f7\u7801\uff1a13631365840,\u95ee\u9898\u5f00\u59cb\u65f6\u95f4\uff1a\u4e09\u5929\u9f50\u524d\u8be6\u7ec6\u5730\u5740\uff1a\u5e7f\u5dde\u5e02\u6d77\u73e0\u533a\u51e4\u9633\u8857\u9053\u9e6d\u6c5f\u897f\u88576\u53f7,\u4e0a\u7f51/\u901a\u8bdd\u95ee\u9898\uff1a\u4e00\u76f4\u4f7f\u7528\u4e0d\u4e86\u7f51\u7edc\u300d,----------,,", "\u5ba2\u6237\u53cd\u6620\u5728\u6700\u8fd1\u4e00\u5468\u5728\u5e7f\u5dde\u5e02\u9ec4\u57d4\u533a\u65b0\u5e84\u67ef\u56ed\u885715\u53f7\u4fe1\u53f7\u4e0d\u597d\uff0c\u5468\u56f4\u7684\u7528\u6237\u4e5f\u662f\u8fd9\u6837\u7684\u60c5\u51b5\uff0c\u5ba2\u6237 \u610f\u89c1\u975e\u5e38\u5927\uff0c\u8bf7\u4e0a\u7ea7\u90e8\u95e8\u5904\u7406"],
"called_number": ["none", "none"]}}
这个就是纯粹的 Unicode 转换成中文,直接参考如下代码:
public String unicodeToCN(String str){
/**
if(str == null)
return null;
if(str.indexOf("u") == -1){
return str;
}else{
str = str.replace("u", "\\\\u");
}
*/
Pattern pattern = Pattern.compile("\\\\u([0-9a-fA-F]{4})");
Matcher matcher = pattern.matcher(str);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String unicode = matcher.group(1);
//同样也是通过 Integer.parseInt(String str, radix) 方式把 十六进制 转化成 十进制
int codePoint = Integer.parseInt(unicode, 16);
//转换成中文
String chinese = new String(new char[] { (char) codePoint });
//Unicode替换中文
matcher.appendReplacement(result, Matcher.quoteReplacement(chinese));
}
matcher.appendTail(result);
return result.toString();
}
总之如果出现类似\u9898 或者请 ; 这种明显可以看出来后面四位是十六进制的,大概率可以转换成 Unicode 编码,然后转换成中文。
另外附上中文 Unicode 的编码范围:[\u4e00-\u9fa5],即从“\u4e00”到“\u9fa5”,共计40869-19968=20901个汉字
Unicode编码,GBK,UTF-8问题可参考另一篇文章:【JAVA】知识——各类编码格式以及样例