文章目录
最近在爬xx段子平台时,发现其使用max_time=1499253150
时间戳来进行分页,json结果里的中文进行了unicode转码,这样避免了response的乱码问题。在java中,如果直接打印unicode编码结果时会直接显示String结果:
@Test
public void unicodePrint(){
System.out.println("unicode \u548c string \u7684\u76f8\u4e92\u8f6c\u6362");
//OutPut: unicode 和 string 的相互转换
}
但是,从流数据中读入再输出结果依旧是\u
开头,原因是在读取过程中\u
被转码成\\u
,需要单独处理。
String和Unicode相互转换
package org.xinyo.util;
import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
/**
* Unicode 和 String 的相互转换,并保留ASCII/Unicode部分
*
* @author CHENG
*
*/
public class UnicodeUtils {
/**
* Unicode转string
*
* @param unicode
* @return
*/
public static String fromUnicode(String unicode) {
// 其中\\\\u\\w{4}为匹配unicode,后面用X代替;((?!X).)*为否定向后(右)环视匹配,匹配不包含X的内容;((?!X).)*+中的加号为占有优先,放弃后续备用路径,提高正则表达式的效率
Pattern pattern = Pattern.compile("(((?!\\\\u\\w{4}).)*+)(\\\\u(\\w{4}+))?(((?!\\\\u\\w{4}).)*+)");
Matcher matcher = pattern.matcher(unicode);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
buffer.append(matcher.group(1));
if (matcher.group(4) != null) {
char letter = (char) Integer.parseInt(matcher.group(4), 16);
buffer.append(letter);
}
buffer.append(matcher.group(5));
}
return buffer.toString();
}
/**
* String转Unicode
*
* @param string
* @return
*/
public static String toUnicode(String string) {
// 其中[\\u0000-\\u007F]
为ASCII码十六进制(Unicode)范围
Pattern pattern = Pattern.compile("([\\u0000-\\u007F]*+)([^\\u0000-\\u007F])?([\\u0000-\\u007F]*+)");
Matcher matcher = pattern.matcher(string);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
buffer.append(matcher.group(1));
if (matcher.group(2)!=null) {
buffer.append(escapeNonAscii(matcher.group(2)));
}
buffer.append(matcher.group(3));
}
return buffer.toString();
}
/**
* 非ASCII转Unicode
* 来源:{@link https://stackoverflow.com/questions/5733931/java-string-unicode-value/14817912#14817912}
* @param str
* @return
*/
private static String escapeNonAscii(String str) {
StringBuilder retStr = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
int cp = Character.codePointAt(str, i);
int charCount = Character.charCount(cp);
if (charCount > 1) {
i += charCount - 1; // 2.
if (i >= str.length()) {
throw new IllegalArgumentException("truncated unexpectedly");
}
}
if (cp < 128) {
retStr.appendCodePoint(cp);
} else {
retStr.append(String.format("\\u%x", cp));
}
}
return retStr.toString();
}
@Test
public void testFromUnicode() {
String string = UnicodeUtils.fromUnicode("unicode \\u548c string \\u7684\\u76f8\\u4e92\\u8f6c\\u6362\\uff0c\\u5e76\\u4fdd\\u7559\\u975e\\u4e2d\\u6587/unicode\\u90e8\\u5206");
System.err.println(string);
}
@Test
public void testToUnicode() throws UnsupportedEncodingException {
String unicode = UnicodeUtils.toUnicode("unicode 和 string 的相互转换,并保留非中文/unicode部分");
System.err.println(unicode);
}
}
没有评论