regex 总览待审核
Emoji 属性 · 码点的标签与派生

一个码点身上的 emoji 标签:六个属性与派生

Basic_Emoji 那页把 U+FE0F(VS16)、U+200D(ZWJ)当成 emoji 序列的「零件」。这页换一个正交的视角: 随便拿一个 code point,Unicode 给它贴了哪几个 emoji 标签?这套标签是码点级二元属性—— \p{Emoji}\p{Emoji_Presentation} 等,共六个。它们和「序列怎么拼」无关, 只回答「这个码点本身是什么」。注意这六个全是码点属性,所以原生 u 模式就能测, 本仓库 @vega/parsing/regex 自研引擎也照样跑——和 RGI 序列页要靠 v字符串属性 \p{RGI_Emoji} 形成对照。

码点探针:测一个码点命中哪几个属性

挑一个码点,看它命中哪几个属性。属性是按单个码点定义的,所以这里只看一个码点 (输入多字符时取第 1 个)。留意几个反直觉的:肤色 🏻 自己就是 Emoji;EmojiEmoji_Presentation(默认文本脸);ZWJ / VS16 是 Emoji_ComponentEmoji

为什么 # * 0–9 算 Emoji?——它们是 keycap 按键 emoji 的底座。1️⃣ 不是单码点,而是三件套拼的:"1" + U+FE0F(VS16,强制 emoji 脸)+ U+20E3(combining enclosing keycap,套上按键方框)。能当底座的恰好只有这 12 个(数字键 + #/*),所以 Unicode 给它们打上 Emoji + Emoji_Component,但裸字符默认仍是文本脸(Emoji_Presentation=No)、也非象形(Extended_Pictographic=No)。0–9 十个全在内:0️⃣…9️⃣

注意和另一路区分:© ® 这类也 Emoji=YesComponent=No——它们不是拼序列的零件,而是自己 + VS16 就从文本脸变 emoji 脸(©️ ❤️ ↩️),属于 Basic_Emoji 页讲的那一路。

六个属性(原生 /\p{…}/u 实测)

派生规则(Unicode 规定):Emoji=No,则 Emoji_PresentationEmoji_ModifierEmoji_Modifier_Base 必为 No——后三者是 Emoji子集,Emoji 是它们的「总开关」。 但 Emoji_ComponentExtended_Pictographic 受这条约束。

谁包含谁:总开关 + 两条正交轴

U+0000~U+10FFFF 全量实测得到的基数与包含关系——三个「派生」属性确实落在 Emoji 内,另外两个各成一轴:

\p{Emoji}1438「这码点能当 emoji 用」的总开关。注意它包含 # * 0–9 和区域码这些非象形成员。
\p{Emoji_Presentation}1219默认就走彩色 emoji 脸,不需要 VS16(😀🚀)。❤▶ 不在其中——默认文本脸。
\p{Emoji_Modifier}5就 5 个肤色修饰符 U+1F3FB–1F3FF。它们本身 Emoji=Yes(反直觉,但属性如此)。
\p{Emoji_Modifier_Base}134肤色修饰的底字符(👋🧑)。😀 不在其中——给它接肤色无效。
↑ 以上 ⊆ Emoji ·· 以下为正交轴(不受 Emoji 总开关约束)
\p{Emoji_Component}146在 emoji 组合里当「零件」:ZWJ / VS16 / keycap / 区域码 / 肤色 / 数字。其中 ZWJ、VS16 等 Emoji=No
\p{Extended_Pictographic}2848最广的象形符号集(含尚未正式列为 emoji 的图形)。但 #/数字/区域码是 Emoji象形,不在其中。

对比扫描:一排码点,六列属性

同一组代表码点,六个属性逐格实测(✓ 命中 / · 落空)。横着看一行,就是这个码点完整的属性标签组合:

和别的页串起来:探针里那些 Emoji=No 的零件(ZWJ U+200D、VS16 U+FE0F)就是 Basic_Emoji 页讲的「胶水」——它们的正式身份正是 \p{Emoji_Component}。 这六个都是码点属性,自研引擎那页能直接 \p{Emoji_Presentation} 匹配; 而把它们拼成一个完整 emoji 要用字符串属性 \p{RGI_Emoji}——那是 RGI 序列页的内容。