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

JavaScript中含特殊Unicode字符的字符串取下标返回替换字符问题

问题产生原因

JavaScript 字符串采用 UTF-16 编码 存储,最小存储单位为16位的码元:

  • 普通 ASCII 字符(如示例中的a/b/c)的 Unicode 码点在 U+0000 ~ U+FFFF 范围内,仅占用1个码元,直接用下标取值可以正常返回对应字符。
  • 你用到的𝖆/𝖇/𝖈属于 Unicode 增补字符集的数学黑体小写字母,码点均超过 U+FFFF,需要占用2个连续码元(即代理对)存储。
    使用weirdString[1]取值时,实际取到的是第一个字符𝖆的第二个代理码元,单独的代理码元不属于合法 Unicode 字符,因此会显示为替换字符�。
可行解决方法
  • 方法1:使用展开运算符或Array.from()按 Unicode 码点拆分字符串
    这两种方法都会自动识别代理对,按完整字符拆分字符串,适用绝大多数单码点特殊字符场景:
var weirdString = "𝖆𝖇𝖈"
// 展开运算符拆分
[...weirdString][1] // 返回 𝖇
// Array.from 拆分
Array.from(weirdString)[1] // 返回 𝖇
  • 方法2:组合使用codePointAt()和String.fromCodePoint()操作
    如果需要手动计算码点位置,可以用这两个方法直接处理完整码点:
var weirdString = "𝖆𝖇𝖈"
// 第一个字符占2个码元,第二个字符的码点起始位置为2
const secondCodePoint = weirdString.codePointAt(2)
String.fromCodePoint(secondCodePoint) // 返回 𝖇
  • 方法3:使用Intl.Segmenter处理复杂字素场景
    如果需要处理带修饰符的 emoji、组合字符等多码点组成的用户感知字符(如👨‍👩‍👧家庭 emoji),可以用国际化分段器按字素簇拆分,准确度最高:
const segmenter = new Intl.Segmenter('zh', { granularity: 'grapheme' })
const charList = Array.from(segmenter.segment(weirdString), item => item.segment)
charList[1] // 返回 𝖇

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:15:04