如何将字符串字符转换为U+FFFF以上的数学字母符号(UTF-32)?
普通字母转数学字母符号的正确方法
问题根源
String.fromCharCode仅支持U+0000到U+FFFF范围内的Unicode码点,而数学字母符号(如𝓐、𝓪)的码点都超过U+FFFF,属于Unicode astral平面字符,因此直接用fromCharCode解析会得到错误的代理对字符(比如示例中的'풳'、'')。
解决方案:使用String.fromCodePoint
String.fromCodePoint支持全范围的Unicode码点(包括U+10000及以上),是处理这类字符的正确API。
转换逻辑
数学字母符号和普通字母的码点有固定差值:
- 数学粗体大写字母(𝓐-𝓩):普通大写字母(A-Z,U+0041-U+005A)的码点加上
0x1D48F(十进制119951),对应目标码点范围U+1D4D0-U+1D4E9。 - 数学粗体小写字母(𝓪-𝔷):普通小写字母(a-z,U+0061-U+007A)的码点加上
0x1D485(十进制119941),对应目标码点范围U+1D4E6-U+1D505。
实现代码
function convertToMathBold(str) { return str.split('').map(char => { const code = char.codePointAt(0); // 处理大写字母 if (code >= 0x41 && code <= 0x5A) { return String.fromCodePoint(code + 0x1D48F); } // 处理小写字母 else if (code >= 0x61 && code <= 0x7A) { return String.fromCodePoint(code + 0x1D485); } // 非字母保持原样 else { return char; } }).join(''); } // 测试 console.log(convertToMathBold("ABCabc")); // 输出:𝓐𝓑𝓒𝓪𝓫𝓬
原方法失败原因
原代码中"A".codePointAt(0) + "𝓐".codePointAt(0)计算结果为0x41 + 0x1D4D0 = 0x1D511,该码点远超过U+FFFF,String.fromCharCode无法正确解析,只能返回错误的代理对字符;而String.fromCodePoint可以直接处理这个高位码点,生成正确的数学字母符号。
内容的提问来源于stack exchange,提问作者Inherent
相关产品推荐
相关产品推荐

