regex 总览待审核
番外 · 源码里写一个码位 &#x… / \u{…} / \1F600

写出一个码位:HTML / CSS / JS 三套转义

字符的编码 那页讲清了「码位 (code point)」是什么 —— 那知道了码位(比如 😀 是 U+1F600),怎么在源码里把它写出来?HTML、CSS、JS 各有一套转义语法: 😀\1F600\u{1F600}。 三套长得像、规则各不同,各有一个易错点:CSS 的转义会贪心吞掉后面的 hex 字符, HTML 的数字引用不认代理对,JS 的 \uXXXX 工作在码元层、能造出「半个字符」。

同一个(串)码位,各处源码里的写法

在哪写写法说明

三条路真的各走一遍 → 渲染出同一个字符

HTML · 实体写进 innerHTML
CSS · content 转义
JS · String.fromCodePoint

易错点一 · CSS:转义在哪结束?——「终结空格」

CSS 的转义是 \ + 1~6 位 hex,没有花括号包边界 —— 解析器会贪心吃 hex 字符, 直到凑满 6 位或撞上非 hex 字符。想在转义后紧跟 A/0~9/a~f 这类字符? 要么加一个终结空格(会被吞掉、不显示),要么把转义补零写满 6 位:

content: "\2014A"
content: "\2014 A"
content: "\002014A"
想写的是 EM DASH(U+2014)后跟字母 A。第一种少了终结空格,A 被吃进转义 —— 浏览器解析出的是码位 U+2014A(CJK 扩展 B 区的某个汉字,系统缺字体时显示占位方块),并没有破折号。
真想显示「转义 + 空格"」?终结空格会被吞,所以要写两个空格,或把空格也转义成 \20。 另外 CSS 转义不只用在字符串里 —— 标识符也靠它:id 以数字开头时选择器得写 #\31 st(1U+0031),JS 里有现成的 CSS.escape('1st') 帮你算。 还有一处「直接写码位」的 CSS 语法是 unicode-range: U+4E00-9FFF, 见 font-features 的 unicode-range 页

易错点二 · HTML:数字引用只认码位,不认代理对

HTML 的字符引用永远工作在码位层:十进制 😀、十六进制 😀, 再大的码位直接写。反过来,把 UTF-16 代理对(字符的编码那页D83D + DE00)拆成两个引用拼不出 😀 —— 代理区 U+D800~DFFF 不是合法字符,每个都被替换成 U+FFFD (�):

源码 码位写法
😀
源码 代理对写法(错误)
��

易错点三 · JS:\uXXXX 在码元层,能造出「半个字符」

JS 字符串按 UTF-16 码元存,\uXXXX(恰 4 位)写的就是一个码元 —— 所以单写一个高位代理 '\uD83D' 完全合法,得到一个 lone surrogate: 长度 1、渲染成 �、传给只收合法 UTF-8 的 API(fetch body、TextEncoder)会被换成 U+FFFD。ES6 的 \u{…} 才工作在码位层。点下面的写法逐个看:

渲染
读数
检测与修复:str.isWellFormed() 查字符串里有没有 lone surrogate, str.toWellFormed() 把它们替换成 U+FFFD(ES2024,现代浏览器均已支持)。 「为什么 astral 字符要拆成两个码元、怎么算」见本系列 字符的编码

速查:一个码位的全部写法

写法用在哪位数astral (>U+FFFF)
😀 / 😀HTML 文本、属性值hex / 十进制,任意位✓ 直接写码位
— 等命名实体HTML 文本(仅限有名字的字符)仅已命名字符
\1F600(+ 终结空格)CSS 字符串、标识符hex 1~6 位
\u{1F600}JS 字符串 / 模板 / 正则(需 u/v)hex 1~6 位
\uD83D\uDE00JS、JSON(它只有这一种)hex 恰 4 位 = 1 码元要手拆代理对
\xE9JShex 恰 2 位✗ 仅 U+0000~00FF
String.fromCodePoint(0x1F600)JS 运行时(读取端是 codePointAt / for...of)
经验法则:HTML 用 &#x…;(和 U+… 直接对得上)、CSS 记得终结空格、 JS 一律 \u{…};只有 JSON 没得选,astral 必须手拆代理对。
延伸阅读:MDN · UTF-16 characters, Unicode code points, and grapheme clusters 把本页 JS 半边讲全:String 按码元工作、lone surrogate 的来源(slice 切半也会造出它)、 isWellFormed / toWellFormed、按码位遍历。「用户眼里的一个字符」还要再往上一层 (字素簇),见本系列 字素簇

🔗 相关链接