1. 程式人生 > >【131】Java把\u開頭的Unicode編碼轉換成漢字

【131】Java把\u開頭的Unicode編碼轉換成漢字

最近工作中遇到需要呼叫第三方介面的需求。第三方介面返回的字串中,會把中文轉義成 \u + Unicode 的形式。因此,我需要再把 \u + Unicode 轉換成漢字。

這裡,我們需要認識到 Java 程式碼對於 \u 字元處理的內外有別。如果是編寫程式的時候,直接在字串變數裡面寫 \u + Unicode ,Java 會自動轉成漢字。但是 Java 程式對於從外部輸入的 \u + Unicode 字元,會把 \u 視作普通字元,相當於 Java 字串中的 "\\u"

下面是工具類程式碼,用於把 \u + Unicode 轉換成漢字。

package zhangchao.common.
unicode; import java.util.regex.Pattern; /** * 字串中存在 反斜槓+u 開頭 的Unicode字元。本類用於把那些Unicode字串轉換成漢字 * @author 張超 * */ public final class UicodeBackslashU { // 單個字元的正則表示式 private static final String singlePattern = "[0-9|a-f|A-F]"; // 4個字元的正則表示式 private static final String pattern = singlePattern + singlePattern +
singlePattern + singlePattern; /** * 把 \\u 開頭的單字轉成漢字,如 \\u6B65 -> 步 * @param str * @return */ private static String ustartToCn(final String str) { StringBuilder sb = new StringBuilder().append("0x") .append(str.substring(2, 6)); Integer codeInteger = Integer.decode(sb.toString
()); int code = codeInteger.intValue(); char c = (char)code; return String.valueOf(c); } /** * 字串是否以Unicode字元開頭。約定Unicode字元以 \\u開頭。 * @param str 字串 * @return true表示以Unicode字元開頭. */ private static boolean isStartWithUnicode(final String str) { if (null == str || str.length() == 0) { return false; } if (!str.startsWith("\\u")) { return false; } // \u6B65 if (str.length() < 6) { return false; } String content = str.substring(2, 6); boolean isMatch = Pattern.matches(pattern, content); return isMatch; } /** * 字串中,所有以 \\u 開頭的UNICODE字串,全部替換成漢字 * @param strParam * @return */ public static String unicodeToCn(final String str) { // 用於構建新的字串 StringBuilder sb = new StringBuilder(); // 從左向右掃描字串。tmpStr是還沒有被掃描的剩餘字串。 // 下面有兩個判斷分支: // 1. 如果剩餘字串是Unicode字元開頭,就把Unicode轉換成漢字,加到StringBuilder中。然後跳過這個Unicode字元。 // 2.反之, 如果剩餘字串不是Unicode字元開頭,把普通字元加入StringBuilder,向右跳過1. int length = str.length(); for (int i = 0; i < length;) { String tmpStr = str.substring(i); if (isStartWithUnicode(tmpStr)) { // 分支1 sb.append(ustartToCn(tmpStr)); i += 6; } else { // 分支2 sb.append(str.substring(i, i + 1)); i++; } } return sb.toString(); } }

下面我們要測試一下程式碼。我們讀取了一個JSON檔案,檔案中有 \u + Unicode 的內容。

讀取檔案的 FileUtils.java:

package zhangchao.common.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 檔案工具類
 * @author 張超
 *
 */
public final class FileUtils {
	
	/**
	 * 讀取檔案內容,並把內容作為字串返回
	 * @param f 要讀取的檔案
	 * @return 字串形式的檔案內容。
	 */
	public static String readAsString(File f) {
		BufferedReader br = null;
		StringBuilder sb = new StringBuilder();
		try {
			br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
			String str = br.readLine();
			while (null != str) {
				sb.append(str).append("\n");
				str = br.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != br) {
				br.close();
				br = null;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}
}

用於測試的主類,TestUnicode.java:

package zhangchao.test;

import zhangchao.common.utils.FileUtils;
import zhangchao.common.unicode.UicodeBackslashU;

import java.io.File;

/**
 * 測試 \\u + Unicode 轉換成漢字
 * @author 張超
 *
 */
public class TestUnicode {

	public static void main(String[] args) {
		String jsonStr = FileUtils.readAsString(new File("src/test/resources/MyJson.json"));
		String str = UicodeBackslashU.unicodeToCn(jsonStr);
		System.out.println(str);
	}

}

MyJson.json 的檔案內容:

{
    "msg":"success",
    "data":{
        "userId":"12363324",
        "collegeName":"\u8BA1\u7B97\u673A\u5B66\u9662",
        "className":"\u8F6F\u4EF6\u4E00\u73ED"
    }
}

程式的執行結果:

{
    "msg":"success",
    "data":{
        "userId":"12363324",
        "collegeName":"計算機學院",
        "className":"軟體一班"
    }
}

下面的圖片解釋了 UicodeBackslashU 類的工作原理:
1.png

在這裡插入圖片描述