杰瑞科技汇

unicode 解码 java

Java 的字符串字面量可以直接支持 Unicode 转义序列,我们也可以通过编程方式,使用 Character 类来将一个整数(码点)转换为字符。

unicode 解码 java-图1
(图片来源网络,侵删)

在字符串字面量中直接使用 Unicode 转义

这是最简单直接的方法,你可以在 Java 源代码的字符串中直接写入 \u 后跟四个十六进制数。

语法

\uXXXX

XXXX 是一个 4 位的十六进制数,代表一个 Unicode 字符的码点。

示例代码

public class UnicodeLiteralExample {
    public static void main(String[] args) {
        // \u4e2d 是 "中" 的 Unicode 码点
        // \u6587 是 "文" 的 Unicode 码点
        String chinese = "\u4e2d\u6587";
        // \u5b66 是 "学" 的 Unicode 码点
        // \u4e60 是 "习" 的 Unicode 码点
        String study = "\u5b66\u4e60";
        System.out.println(chinese); // 输出: 中文
        System.out.println(study);  // 输出: 学习
        // 也可以混合使用普通字符和 Unicode 转义
        String mixed = "Hello, \u4e16\u754c!"; // \u4e16是"世", \u754c是"界"
        System.out.println(mixed); // 输出: Hello, 世界!
    }
}

注意:这种方法在编译时就已经完成了转换,当 .java 文件被编译成 .class 文件时,\uXXXX 会被替换成它所代表的字符,在反编译 .class 文件时,你看到的将是实际的字符而不是 \uXXXX 序列。


通过 Character.toString() 进行编程解码

如果你有一个 Unicode 码点的整数值,并想在运行时将其转换为字符串,可以使用 Character 类。

unicode 解码 java-图2
(图片来源网络,侵删)

示例代码

假设我们有一个整数值,代表 Unicode 码点。

public class UnicodeDecodeProgrammatically {
    public static void main(String[] args) {
        // "中" 的 Unicode 码点是 0x4E2D,即十进制的 20013
        int codePoint = 0x4E2D;
        // Character.toString() 方法可以将一个码点转换为字符串
        String character = Character.toString(codePoint);
        System.out.println("码点: " + codePoint);
        System.out.println("对应的字符: " + character); // 输出: 中
        // 也可以使用 char 类型 (对于基本多文种平面 BMP 内的字符)
        char charValue = (char) codePoint;
        String fromChar = Character.toString(charValue);
        System.out.println("从 char 转换的字符: " + fromChar); // 输出: 中
    }
}

处理超出 BMP 的字符(代理对)

Unicode 字符非常多,很多字符的码点超过了 0xFFFF(即基本多文种平面,BMP),这些字符需要用两个 char 值来表示,这被称为“代理对”(Surrogate Pair)。

  • 第一个 char 是“高位代理”(High Surrogate),范围是 \uD800\uDBFF
  • 第二个 char 是“低位代理”(Low Surrogate),范围是 \uDC00\uDFFF

对于这些字符,直接使用 char 会丢失信息,必须使用 int 类型的码点。

示例代码

Emoji 表情符号是典型的超出 BMP 的字符。“😂”的码点是 0x1F602

public class SupplementaryCharacterExample {
    public static void main(String[] args) {
        // Emoji "笑哭" 的码点是 0x1F602
        int codePoint = 0x1F602;
        // 正确的方式:使用 int 码点和 Character.toString()
        String emoji = Character.toString(codePoint);
        System.out.println("使用码点解码: " + emoji); // 输出: 😂
        // 错误的方式:尝试用 char
        // char c = (char) codePoint; // 这样会得到一个错误的值
        // System.out.println(c); // 输出可能是一个无法识别的符号或 '?'
        // 如果你有一个代理对(两个 char),如何转换?
        char[] surrogatePair = Character.toChars(codePoint);
        System.out.println("代理对的长度: " + surrogatePair.length); // 输出: 2
        System.out.println("高位代理: " + surrogatePair[0]); // 输出一个高位代理字符,如 \uD83D
        System.out.println("低位代理: " + surrogatePair[1]); // 输出一个低位代理字符,如 \uDE02
        // 同样,可以用 String 的构造函数从 char 数组创建字符串
        String fromSurrogate = new String(surrogatePair);
        System.out.println("从代理对创建的字符串: " + fromSurrogate); // 输出: 😂
    }
}

从包含 \uXXXX 格式字符串的文本中解码

你可能会从文件、网络或用户输入中获取一个像 "\\u4e2d\\u6587" 这样的字符串,并希望将其解码成“中文”,这种情况下,你需要自己解析这个字符串。

示例代码

下面的方法会扫描字符串,查找 \u 开头的模式,并将其替换为对应的字符。

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DecodeUnicodeFromString {
    public static void main(String[] args) {
        String encodedString = "Hello, \\u4e2d\\u56fd\\uff01"; // 注意:在字符串字面量中,反斜杠需要双写
        String decodedString = decodeUnicodeEscapes(encodedString);
        System.out.println("解码前: " + encodedString);
        System.out.println("解码后: " + decodedString); // 输出: Hello, 中国!
    }
    public static String decodeUnicodeEscapes(String str) {
        // 使用正则表达式匹配 \uXXXX 模式
        Pattern pattern = Pattern.compile("\\\\u([0-9a-fA-F]{4})");
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            // 找到匹配的十六进制字符串
            String hexStr = matcher.group(1);
            // 将十六进制字符串转换为整数(码点)
            int codePoint = Integer.parseInt(hexStr, 16);
            // 将码点转换为字符
            char ch = (char) codePoint;
            // 将匹配到的 \uXXXX 替换为字符
            matcher.appendReplacement(sb, String.valueOf(ch));
        }
        // 将剩余部分添加到结果中
        matcher.appendTail(sb);
        return sb.toString();
    }
}

重要提示:当这个包含 \uXXXX 的字符串本身是 Java 字符串字面量时,你需要对反斜杠进行转义,所以写成 "\\u4e2d",如果你是从文件中直接读取的文本,它可能就是 \u4e2d 的形式,不需要双反斜杠。


场景 推荐方法 示例
在源代码中直接写字符 Unicode 转义序列 String s = "\u4e2d";
运行时从整数(码点)转 Character.toString(int codePoint) Character.toString(0x4e2d);
处理 Emoji 等特殊字符 Character.toChars(int codePoint) char[] chars = Character.toChars(0x1F602);
从文本(如文件)中解码 \uXXXX 正则表达式替换 使用 PatternMatcher 解析并替换。

选择哪种方法取决于你的具体需求,对于在代码中硬编码的字符,方法一最方便,对于动态处理,方法二和方法三更合适,对于处理来自外部数据的字符串,方法四是必要的。

分享:
扫描分享到社交APP
上一篇
下一篇