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

如何在JavaScript中将混合Unicode字符(含代理对)拆分至数组

问题

现有如下字符串数组:

unicodes = ["\ua7a8\ua7a9\ud800\udf30\ud800\udf31\ud800\udf32\ud800\udf33\ud800\udf34\ud800\udf35\ud800\udf36\ud800\udf37\ud800\udf38\ud800\udf39\ud800\udf3a\ud800\udf3b\ud800\udf3c\ud800\udf3d"]

希望将每个Unicode字符(包括U+FFFF以上的代理对组合字符)单独存入数组,最终形式如:

["\ua7a8","\ua7a9","\ud800\udf30"]

尝试了以下代码:

unicodes = ["\ua7a8\ua7a9\ud800\udf30\ud800\udf31\ud800\udf32\ud800\udf33\ud800\udf34\ud800\udf35\ud800\udf36\ud800\udf37\ud800\udf38\ud800\udf39\ud800\udf3a\ud800\udf3b\ud800\udf3c\ud800\udf3d"]
var collectedUnicodes = []

for (let i=0; i < unicodes.length; i++) {
    collectedUnicodes = collectedUnicodes.concat(unicodes[i].split(""))
}

console.log(collectedUnicodes)

返回结果中,U+FFFF以上的Unicode代理对被拆分为两个独立元素:

['Ꞩ', 'ꞩ', '\uD800', '\uDF30', '\uD800', '\uDF31', '\uD800', '\uDF32', '\uD800', '\uDF33', '\uD800', '\uDF34', '\uD800', '\uDF35', '\uD800', '\uDF36', '\uD800', '\uDF37', '\uD800', '\uDF38', '\uD800', '\uDF39', '\uD800', '\uDF3A', '\uD800', '\uDF3B', '\uD800', '\uDF3C', '\uD800', '\uDF3D']

需要将代理对组合的完整Unicode字符作为单个数组元素,如何正确实现?

解决方案

方法1:使用ES6扩展运算符(...)

扩展运算符会自动识别Unicode代理对,将其作为单个元素处理:

const unicodes = ["\ua7a8\ua7a9\ud800\udf30\ud800\udf31\ud800\udf32\ud800\udf33\ud800\udf34\ud800\udf35\ud800\udf36\ud800\udf37\ud800\udf38\ud800\udf39\ud800\udf3a\ud800\udf3b\ud800\udf3c\ud800\udf3d"];
const collectedUnicodes = [];

for (const str of unicodes) {
  collectedUnicodes.push(...str);
}

console.log(collectedUnicodes);

方法2:使用Array.from()

Array.from()同样能正确处理Unicode代理对,将字符串转换为包含完整字符的数组:

const unicodes = ["\ua7a8\ua7a9\ud800\udf30\ud800\udf31\ud800\udf32\ud800\udf33\ud800\udf34\ud800\udf35\ud800\udf36\ud800\udf37\ud800\udf38\ud800\udf39\ud800\udf3a\ud800\udf3b\ud800\udf3c\ud800\udf3d"];
const collectedUnicodes = [];

for (const str of unicodes) {
  collectedUnicodes = collectedUnicodes.concat(Array.from(str));
}

console.log(collectedUnicodes);

方法3:使用正则表达式匹配

通过正则表达式匹配所有Unicode字符(包括代理对):

const unicodes = ["\ua7a8\ua7a9\ud800\udf30\ud800\udf31\ud800\udf32\ud800\udf33\ud800\udf34\ud800\udf35\ud800\udf36\ud800\udf37\ud800\udf38\ud800\udf39\ud800\udf3a\ud800\udf3b\ud800\udf3c\ud800\udf3d"];
const collectedUnicodes = [];
// 匹配所有Unicode字符的正则
const unicodeRegex = /[\s\S]/gu;

for (const str of unicodes) {
  collectedUnicodes = collectedUnicodes.concat(str.match(unicodeRegex));
}

console.log(collectedUnicodes);

原理说明

原来的split("")方法是基于UTF-16编码的代码单元拆分的,而U+FFFF以上的Unicode字符在UTF-16中是用两个代码单元(代理对)表示的,所以会被拆分成两个元素。而上面的三种方法都能识别完整的Unicode字符(包括代理对组合的字符),从而将每个完整字符作为数组的一个元素。

内容的提问来源于stack exchange,提问作者karl-police

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:05:23