You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何正确拆分包含多码点字符(如Emoji)的字符串?

在Java中正确处理包含Emoji的字符串拆分问题

这个问题太常见了!你遇到的情况是因为像🆗这类Emoji属于Unicode代理对——Java里的char是16位的,只能覆盖Unicode基本多语言平面(BMP)的字符,而很多复杂Emoji、特殊符号属于补充平面,需要用两个char(高代理字符+低代理字符)组合表示。toCharArray()方法会直接把这两个char拆分开,所以你看到了两个无法正常显示的问号(本质是单独的代理字符)。

要实现按完整字符(包括Emoji)拆分的需求,有两种实用方法:

方法一:使用Unicode代码点(推荐)

Java 8及以上版本提供了String.codePoints()方法,可以直接获取字符串中所有Unicode代码点(每个代码点对应一个完整的字符,不管它是1个还是2个char)。我们可以把这些代码点转回字符串,轻松得到期望的结果:

String emojiStr = "test 🆗";
// 获取所有Unicode代码点数组
int[] codePoints = emojiStr.codePoints().toArray();

// 将每个代码点转换为对应的完整字符(字符串形式)
String[] fullChars = new String[codePoints.length];
for (int i = 0; i < codePoints.length; i++) {
    fullChars[i] = new String(Character.toChars(codePoints[i]));
}

// 测试输出:["t", "e", "s", "t", " ", "🆗"]
for (String ch : fullChars) {
    System.out.println(ch);
}

这种方式不需要手动判断代理对,代码简洁且不易出错,是处理这类问题的首选方案。

方法二:手动判断代理对并合并

如果你需要更底层的遍历控制,可以通过Character.isHighSurrogate()方法判断当前char是否是代理对的高代理字符,然后和下一个低代理字符合并成完整的Emoji:

String emojiStr = "test 🆗";
List<String> fullCharList = new ArrayList<>();

for (int i = 0; i < emojiStr.length(); ) {
    char currentChar = emojiStr.charAt(i);
    // 判断当前字符是否是高代理,且存在下一个字符
    if (Character.isHighSurrogate(currentChar) && i + 1 < emojiStr.length()) {
        // 截取代理对的两个字符,组成完整Emoji
        fullCharList.add(emojiStr.substring(i, i + 2));
        i += 2; // 跳过下一个低代理字符
    } else {
        fullCharList.add(String.valueOf(currentChar));
        i += 1;
    }
}

// 转换为数组的话可以用 fullCharList.toArray(new String[0])

这种方法适合需要精细控制遍历过程的场景,但代码相对繁琐一些。


内容的提问来源于stack exchange,提问作者V0idst4r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:21:29