regex 总览待审核
基础 · \p{S} 符号四子类

\p{S} 符号四子类:| 是符号、^ 不是重音、😀 归哪一类

接着 \p{P} 标点七子类那页——码点档案的 gc 表里, 和 \p{P} 并排的还有一行 Symbol(符号)\p{S},它切成 4 个子类 Sm Sc Sk So(数学 / 货币 / 修饰 / 其他)。反直觉的归类全在这里:+ | ~数学符号 Sm(不是标点)、$ 货币 Sc^ ´ ¨修饰符号 Sk(看着像重音、其实是独立符号)、而 😀 © 全挤在 catch-all 子类 So 里。这页用原生 /\p{…}/u 把这 4 个子类实测着看清:每个码点恰好属于一个 gc 子类,首字母 S 就是它的大类。

gc 子类是「身份」,不是「住址」。 一个码点的 General_Category 在 UCD 里是单值的—— | 的 gc 永远是 Sm,无论它在代码里当「或」、当管道还是当绝对值竖线。这和 Block(住址)不同:住址只说它住哪段码位。本页所有「是不是某子类」都用 /^\p{…}$/u 当场测,不是查表。

先分清:这些「看着像符号」的其实不是 \p{S}

挑选符号最常见的误区,是凭字形归类。下面这些天天见、像极了符号的字符,gc 其实落在标点 P字母 L 里—— 每行的 \p{S} 都是当场 /^\p{S}$/u 测出来的 No:

两点结论:其一 百分号 % 、角分秒 看着是「记号」,gc 却是 标点 Po(和脚注符号同桶,见标点七子类);§ Unicode 6.1 之前曾是 So,之后并入 Po。其二 微符号 µ(U+00B5)、欧姆常用的 Ω(其实是希腊大写 Omega U+03A9)、抑扬符 ˆ(U+02C6)看着是符号,gc 却是字母(Ll / Lu / Lm)—— 「长得像」从来推不出「是哪类」。

\p{S} 的四个子类(Unicode 17.0 实测基数)

每个码点恰好属于其中一个。So 是 catch-all 子类,独占近九成:

子类名称码点数典型成员
SoOther 其他符号7468© ® ™ ° № ℃ ★ ♠ ♥ ☑ ░ █ 😀
SmMath 数学符号960+ < = > | ~ ± × ÷ ¬ ∑ ∫ ∞ → ↔
SkModifier 修饰符号125^ ` ´ ¨ ˜ ¯ ¸ ˚
ScCurrency 货币符号64$ ¢ £ ¥ € ₩ ₹ ₿ ฿ ¤
合计 8617 个(Unicode 17.0)。随版本会微涨;计数 = 全码空间逐码点 /\p{…}/u 枚举所得。So 一类占 87%——emoji 几乎都在这一类里。

探针:任意字符落在哪个子类

输入一个字符,实时测它是不是 \p{S}、是 4 子类里的哪一个;不是符号时报它真实的大类。 试试 |(管道竟是数学符号 Sm)、^(脱字符是修饰符号 Sk)、%(百分号不是符号,是标点 Po)、😀(emoji 是 So)。

逐项原生 /^\p{…}$/u 实测

四子类着色器:把符号从文本里挑出来上色

粘一段含各种符号的文本,逐码点把属于 \p{S} 的字符按 4 子类上色,其余字符灰显——看 gc 怎么在真实符号上切分:

全量速查:8617 个 \p{S} 符号

把四个子类全部 8617 个 \p{S} 码点列出来——逐码点 /\p{S}/u 实测筛出,先按 gc 子类、再按 Unicode block 分组。点子类 chip 切换;搜索支持 码位 hex(如 2103U+2103)、 Unicode 名(如 degreearrow)、直接粘一个字符,或块名(如 currencyletterlike)。

So 占了近九成。 7468 个 So绝大多数是 emoji 与 CJK 兼容符号——本页只把它们和 Sm/Sc/Sk 并列计数; emoji 的拆解见 Basic_Emoji 等几页,「画图用」的那撮见 形状符号。 点子类按钮切换,只渲染选中的那一类(默认 Sm),所以即便 So 有 7468 个也不卡顿;搜索时跨全部 4 类找。

深挖一:Sm 全是 \p{Math},So 大多不是

Sm(gc 子类)和 \p{Math}(二元属性)常被当成一回事,其实是两套坐标: gc 子类是单值身份,Math能跨着 gc 切的标签。实测下来——全部 960 个 SmMath=Yes(Sm ⊊ Math), 但 Math 还伸进字母(𝐀 ℵ)、少量 So(★ ♠ 等几何/扑克记号)等;反过来 Sc 货币一个都不是 Math、占地最大的 So 也只有零头是:

所以「数学符号」有两种问法:按 gc 问 \p{Sm} 得到 960 个「形状就是算符」的字;按属性问 \p{Math} 得到 2322 个「数学语境会用」的字(含被借用的字母与记号)。详见 \p{Math} 全量速查——那页正是把这 2322 个全列了出来。

深挖二:Sk 间隔修饰符 vs Mn 组合记号

^ ´ ¨ 这些看着像「重音 / 声调符」,gc 却是 Symbol, modifier(Sk)——它们是独立、占一格的字符, 自己就能打出来。这和真正的组合记号 Mn(Mark, nonspacing)是两回事:后者零宽、必须附在前一个字母上叠加渲染。 同一种「帽子」,Unicode 备了两份(下面每个 gc 当场实测,组合记号前缀 占位才看得见):

同一段「修饰符」区里也分三类。Spacing Modifier Letters 块(U+02B0–02FF)里:发音符号 ˆ(U+02C6)ˉ(U+02C9)其实是字母 Lm(Letter, modifier)、不是 Sk;而 ˜(U+02DC) ˚(U+02DA)才是 Sk。判定一律以 gc 为准,别按所在块或长相猜

深挖三: So,且是 NFKC 会拆开的兼容字符

摄氏 (U+2103)、华氏 (U+2109)的 gc 都是 So——不是标点、不是 Sm、也不是字母, 和 emoji 😀 同属「其他符号」So(😀 的 gc 也是 So)。但它们还有一层身份:住在 Letterlike Symbols 区(U+2100–214F)、是为旧编码 / CJK 等宽排版预先组合好兼容字符。 下面每行的 gc 与 NFKC 归一化都是当场 normalize('NFKC') 实测:

它们是「兼容字符」,日常不该用。 的 NFKC 分解就是 °C / °F——规范文本里应写 度数符号 °(U+00B0,也是 So)+ 字母 C,而不是这个预组合单字。否则 '℃' !== '°C'; 比较 / 查重前先 normalize('NFKC')(细节见 regex 系列的 归一化页)。 同区更隐蔽的例外:住在 Letterlike Symbols 区 ≠ gc 是符号。 紧挨着的 Ω OHM SIGN(U+2126)和 K KELVIN SIGN(U+212A)长得像符号,gc 却是 Lu(大写字母),而且已被弃用——canonical 等价于 普通的希腊 Ω(U+03A9)/ 拉丁 K(U+004B),连 NFC 都会把它们折叠掉(Å ANGSTROM U+212B → Å U+00C5 同理)。所以「住在 Letterlike Symbols 区」不代表 gc 是符号:℃ ℉ °So, Ω K Å 反而是字母。 三种「看着都像记号」凑齐了:预组合兼容字符 (So,NFKC 拆成 °C)、管道符 |(Sm)、 脚注用的 * †(Po,见 标点七子类)——同样像符号,gc 分属 symbol(S)与标点(P)两个大类、So / Sm / Po 三个子类。 catch-all 子类 So 里都有什么? 7468 个,是 \p{S} 里最大的:版权商标 © ® 、 度量记号 ° 、花色 绝大多数 emoji(😀 的 gc 就是 So), 以及在纯文本里画图的形状(░ █ ▰ ■ ●)——后者单独拆在 形状符号 \p{So}那页。 它和标点里的 Po 一样:不属于前面任何专门子类的成员都归入此类 和别的页串起来:本页是 码点的档案 \p{…} 里 gc 表中 \p{S} 那一行的展开,和 \p{P} 标点七子类是一对姊妹页 (一个切符号、一个切标点)。Sm\p{Math} 的关系在 \p{Math} 全量速查;So 里「用来画图」的那撮在 形状符号

相关链接