版本更新:18.0 与 11328 个小篆
\p{…} 查的是 UCD 那份档案,而档案每年换一版。2026 年 9 月 16 日发布的 Unicode 18.0 给码空间添了 13007 个码点,总量到 172808。数量本身不是重点,落点才是:新码点归到哪个 script、落在哪个 plane、勾了哪些二元属性,决定一条写好多年的正则在引擎升级后会不会突然多命中一万个字符。本页按这几栏拆开 18.0
这一版。
1 · 每年一版的节奏
Unicode 自 14.0 起固定每年 9 月发一版,版本号只进整数位。总量曲线并不匀速:1.0.1(1992)把 CJK 一次性收进来,总量从 7129 跳到 28327;3.1(2001)第一次用上补充平面,一版加进 44946 个,其中 42711 个是 CJK 扩展 B;此后二十年是每版几千个的稳定增长,直到 18.0 又跳了一次。
UCD 里记录「某个码点在哪一版被分配」的属性叫 Age(数据在 DerivedAge.txt)。JS 的 \p{…} 不支持它,处境和 Block 那一栏一样(见 \p{…} 属性类 §7):想按版本圈码点,只能自己带一份表。
注 · 图 1-1 的「字符总数」按官方口径算,只数 graphic 与 format 两类。UnicodeData-18.0.0.txt 枚举出 312389 个已分配码点,扣掉 2048 个 surrogate、137468 个私用区码点与 65 个 Cc 控制符,余下正好是官方公布的
172808。私用区占已分配码点的四成还多,却一个字符也没定义,所以它不进这个数(见 不是用来写字的码点 §2)。
2 · 新增字符的去向
13007 个新码点散在 33 个 block 里,分布极不均匀:Seal 一个 block 占掉 87.1%,排第二的 Jurchen 是 914 个,后面二十多个 block 只有个位数。按用途归堆,古文字 12623 个(97.0%)、现代文字 224 个、符号与 emoji 160 个,这一版几乎整个是给历史文献用的。
新 emoji 共九个:U+1F6D9 LIGHTHOUSE、U+1FA8B METEOR、U+1FA8C ERASER、U+1FA8D NET WITH HANDLE、U+1FACC MONARCH BUTTERFLY、U+1FADD PICKLE、U+1FAEB CRACKING FACE,以及 U+1FAF9 与
U+1FAFA 一对左右指向的 THUMB SIGN,合计占这一版的 0.07%。另有三个货币符号 U+20C2–U+20C4(rufiyaa、UAE dirham、Omani rial)。两个 THUMB SIGN 可接肤色 modifier,所以 Emoji 18.0 的新增序列数比码点数多(肤色序列的构成见
RGI 序列 §4)。
3 · 独立 script 的理由
11328 个小篆占 U+3D000–U+3FC3F,整块用满。它们的官方名字逐个由码点算出,形如 SMALL SEAL CHARACTER-3D000,与 CJK 统一表意文字同一种命名法;gc 是 Lo,Script 却是一个新值 Seal,不是 Han。
Han 统一 合并的是同一个抽象字在中日韩的写法差异,判据是 Source Separation Rule:来源标准里本就分开的保持分开,否则合成一个码点。小篆与楷书之间不是这种关系。它是同一批字在两千年尺度上的字体演变,没有哪个来源标准把二者登记成同一个字的两种地区写法。于是 18.0
给它单开一套 script,Scripts.txt 的取值从 174 增到 177,另两个新值是 Jurchen 与 Proto_Cuneiform。
小篆的 glyph 底本是《说文解字》(约 100 CE):每个码点对应书中一个篆文字头,等于拿一本书当了 glyph 的标准件。
警示 · 这个做法在提案阶段就有公开异议。Language Log 上 Victor Mair 主持的讨论串里,Jonathan Smith 的意见是:真实的秦汉印章与刻石上的篆文与《说文》摹本并不一致,把后者认作字符身份,是在给「异体」发码点。提案文档 usage 一栏填的是 RARE、user community 一栏填的是 NO。这些是公开记录而非本页的判断,但它们指向同一件事:不要指望这批码点像 CJK 扩展那样进入日常文本。
4 · Plane 3 的填充
小篆落在 Plane 3,即 TIP(Tertiary Ideographic Plane),范围 U+30000–U+3FFFF。这个平面此前只住着 CJK 扩展 G / H / J 三家,共 13429 个已分配码点,其余五万多个码位空着。18.0 之后已分配码点变成 24757 个,占平面的 37.8%。
注 · Seal 没有紧接 CJK 扩展 J 排下去,中间空着 U+33480–U+3CFFF 近四万个码位。官方的 TIP 路线图把整个平面标给 CJK 统一表意文字与 Old Hanzi 一系(商代甲骨文、西周金文、春秋战国文字),但这段空白在路线图上只写作
unassigned,没有逐段指派给某种具体字体,也没有给出为什么是这个起点。选 U+3D000 而不是 U+33480 的理由,本页没有找到公开依据。
5 · Ideographic 与 Unified_Ideograph 的分岔
小篆勾了 Ideographic,没勾 Unified_Ideograph。两个属性名长得像,18.0 之后的基数却分道扬镳:\p{Ideographic} 从 110943 涨到 123244,多出的 12301 个里 11328 个是小篆、965 个是女真文,余下 8 个散落别处;\p{Unified_Ideograph} 从 101996 只涨到 101997,那 1
个是补进 CJK 扩展 D 的新字。\p{Script=Han} 同样纹丝不动。
同一句「提取文本里的汉字」,写法不同,引擎升级后的行为也不同:\p{sc=Han} 与 \p{Unified_Ideograph} 的匹配面几乎不变,\p{Ideographic} 会多收一万两千个小篆与女真字。选哪个,取决于「汉字」指的是现代通用字,还是连历史字体一起算。
建议 · 这类「属性名相近、基数不同」的疑问,验证成本很低:把 0 到 0x10FFFF 逐码点跑一遍数命中数即可,全量扫一次在 Node 上是秒级。本页的 110943 与 101996 两个数就是这么测出来的(Node 26.8.1、ICU 78.3、内嵌 UCD 17.0);123244 与 101997 则是拿 18.0 的
PropList.txt 逐区间累加得到,两套数字各自独立,正好互相验算。
6 · 引擎与字体的滞后
标准发布不等于正则能用。\p{…} 的行为取决于引擎内嵌的哪一版 UCD,这个版本通常落后标准一到两年。要紧的是失败方式:引擎不认识 Seal 这个 script 值时,/\p{Script=Seal}/u 抛的是
SyntaxError: Invalid property name,整条正则在构造期就死掉,而不是构造成功、匹配不到。未分配码点则相反,U+3D000 在旧引擎上只是安静地 gc=Cn,从匹配结果上与「这段文本里没有这种字」无从区分。两种滞后一硬一软,排查手法完全不同(兼容性据本机实测,核对于 2026-09)。
注 · 图 6-1 的版本探针原本打算照二手报道列 18.0 的新 script 名单,那份名单里有 Chisoi。拿 Scripts-17.0.0.txt 与 Scripts-18.0.0.txt 求差集后,新增值只有 Jurchen、Proto_Cuneiform、Seal 三个,Chisoi 在
17.0 的名单里同样查不到。探针改用差集算出的名单,各版的 script 值也一并按这个办法核过一遍。
警示 · 字体比引擎还慢。U+3D000 即便在认识它的引擎上也画不出 glyph,系统字体里没有小篆,屏幕上是豆腐块。「这串码点合不合法」与「这台设备画不画得出」是两个独立的问题,后者的测法见 检测 emoji 支持。本系列 regex.ts 内嵌的
block 区间表已经换成 18.0.0 的 353 条,于是同一页上会出现 block 表认得 Seal、而 \p{…} 还不认得的错位,这正是两层滞后的直观样子。
7 · 参考文献
- Unicode. The Unicode Standard, Version 18.0.0. 本版的正式发布说明:新增字符数、三个新 script 与七个新 block 的清单。unicode.org
- Unicode. UAX #44: Unicode Character Database.
DerivedAge.txt、PropList.txt、Blocks.txt的格式定义,本页所有计数都由这几份文件算出。unicode.org - Cook, R. Unicode Seal Script Encoding Project. 小篆提案的工作站点:glyph 来源、编码原则与逐字对照表。corp.unicode.org
- Mair, V. (2026, January 15). Seal script in Unicode. Language Log. 讨论串里含对《说文》摹本作为 glyph 标准件的质疑。languagelog.ldc.upenn.edu
- Unicode. Roadmap to the TIP. Plane 3 的长期规划与各段的预留状态。unicode.org