unicode编码简而言之就是将每一个字符用16位2进制数标识。但是通常都用4位的16进制数标识。 例如:
1)中文字符串"你好"的unicode码为:\u60\u597d;
2)英文字符串"ab"的unicode码为:\u0061\u0062;
其中\u是标识unicode码用的,后面的4位16进制数则是对应字符的unicode码。
写爬虫的过程中,经常遇到一些网站的中文是经过Unicode转码的。在对网页进行解析时,需要将其进行转码,转为中文字符。
例如:
\u30102017\u534e\u4e3aHC\u5927\u4f1a\u76f4\u64ad\u3011\u6700\u5168\u3001\u6700\u9707\u64bc\u7684HC\u73b0\u573a\u7167\u7247\u770b\u8fd9\u91cc\uff01\uff01\uff01
对应的中文是:
【2017华为HC大会直播】最全、最震撼的HC现场照片看这里!!!
unicode码在J2EE项目中应用广泛,java对unicode码提供了很好的支持。例如国际化,则是unicode的经典运用。那么unicode的编码规则具体是什么,如何用程序实现?
1.unicode编码规则
unicode码对每一个字符用4位16进制数表示。具体规则是:将一个字符(char)的高8位与低8位分别取出,转化为16进制数,如果转化的16进制数的长度不足2位,则在其后补0,然后将高、低8位转成的16进制字符串拼接起来并在前面补上"\u" 即可。
2.普通转码
对直接的字符串转码可以用一下方式,但是对于网络中爬的数据却是无效的。
String unicode = "\u30102017\u534e\u4e3aHC\u5927\u4f1a\u76f4\u64ad\u3011\u6700\u5168\u3001\u6700\u9707\u64bc\u7684HC\u73b0\u573a\u7167"; String result = new String(unicode.getBytes("UTF-8"), "UTF-8");
3.Unicode转码成String:
public static String decodeUnicode(String str) { Charset set = Charset.forName("UTF-16"); Pattern p = Pattern.compile("\\\\u([0-9a-fA-F]{4})"); Matcher m = p.matcher(str); int start = 0; int start2 = 0; StringBuffer sb = new StringBuffer(); while (m.find(start)) { start2 = m.start(); if (start2 > start) { String seg = str.substring(start, start2); sb.append(seg); } String code = m.group(1); int i = Integer.valueOf(code, 16); byte[] bb = new byte[4]; bb[0] = (byte) ((i >> 8) & 0xFF); bb[1] = (byte) (i & 0xFF); ByteBuffer b = ByteBuffer.wrap(bb); sb.append(String.valueOf(set.decode(b)).trim()); start = m.end(); } start2 = str.length(); if (start2 > start) { String seg = str.substring(start, start2); sb.append(seg); } return sb.toString(); }
4.当然也可以将String转换成Unicode:
public static String stringYoUnicode(String str) { str = (str == null ? "" : str); String tmp; StringBuffer sb = new StringBuffer(1000); char c; int i, j; sb.setLength(0); for (i = 0; i < str.length(); i++) { c = str.charAt(i); sb.append("\\u"); j = (c >>> 8); // 取出高8位 tmp = Integer.toHexString(j); if (tmp.length() == 1) sb.append("0"); sb.append(tmp); j = (c & 0xFF); // 取出低8位 tmp = Integer.toHexString(j); if (tmp.length() == 1) sb.append("0"); sb.append(tmp); } return (new String(sb)); }