Emoji Unicode 速查表 - Emoji 表情符号编码大全

Emoji 在屏上看着正常,却常让数据库列存不下、或在 JSON/接口传输中变成乱码。本表按类别列出常用 Emoji 的码点,并解释代理对(surrogate pair)、ZWJ 联合序列(如家庭 Emoji 由多个码组合)、以及 UTF-8 存储长度这些坑。做前端显示、后端落库、跨平台传输时常来对照。读完能正确评估"这个 Emoji 要占几个码点/几字节"。

参考手册·共 48 条命令·最后更新 2026-07-21
emojiunicode表情

典型使用场景

面向做表情选择器、消息通知渲染、搜索过滤或去重统计的开发者。本表收录 48 个高频 emoji 的 Unicode 码位与名称:表情类(U+1F600 起)、手势类(U+1F44D 起)、动物、食物、运动与器物。核心价值在于码位本身——emoji 在 UTF-8 下占 4 字节、代理对在 JS 里是两个 code unit,这些都要求你记住确切码位才能做过滤、去重与长度计算;名称(如 grinning face)则是与 Unicode 标准对齐的检索关键词。

笑脸与情感 10

😀 U+1F600
笑脸 grinning face
😂 U+1F602
笑哭 face with tears of joy
😊 U+1F60A
微笑 smiling face with smiling eyes
😍 U+1F60D
花痴 smiling face with heart-eyes
😎 U+1F60E
墨镜 smiling face with sunglasses
😭 U+1F62D
大哭 loudly crying face
😡 U+1F621
生气 pouting face
👍 U+1F44D
点赞 thumbs up
👎 U+1F44E
踩 thumbs down
👏 U+1F44F
鼓掌 clapping hands

手势 6

🙏 U+1F64F
祈祷 folded hands
🤝 U+1F91D
握手 handshake
✌️ U+270C
胜利 victory hand
🤞 U+1F91E
交叉手指 crossed fingers
🤘 U+1F918
摇滚 sign of the horns
👌 U+1F44C
OK 手势 OK hand

心形 6

❤️ U+2764
红心 red heart
💔 U+1F494
心碎 broken heart
💕 U+1F495
两颗心 two hearts
💖 U+1F496
闪亮心 sparkling heart
💗 U+1F497
成长心 growing heart
💘 U+1F498
箭心 heart with arrow

动物 10

🐶 U+1F436
狗 dog face
🐱 U+1F431
猫 cat face
🐭 U+1F42D
老鼠 mouse face
🐰 U+1F430
兔子 rabbit face
🦊 U+1F98A
狐狸 fox face
🐻 U+1F43B
熊 bear face
🐼 U+1F43C
熊猫 panda face
🐨 U+1F428
考拉 koala
🐯 U+1F42F
老虎 tiger face
🦁 U+1F981
狮子 lion face

食物 8

🍎 U+1F34E
苹果 red apple
🍕 U+1F355
披萨 pizza
🍔 U+1F354
汉堡 hamburger
🍟 U+1F35F
薯条 french fries
🌭 U+1F32D
热狗 hot dog
🍿 U+1F37F
爆米花 popcorn
☕ U+2615
咖啡 hot beverage
🍺 U+1F37A
啤酒 beer mug

活动与物品 8

⚽ U+26BD
足球 soccer ball
🏀 U+1F3C0
篮球 basketball
🎮 U+1F3AE
游戏手柄 video game
🎵 U+1F3B5
音符 musical note
🎉 U+1F389
派对拉炮 party popper
🎁 U+1F381
礼物 wrapped gift
📱 U+1F4F1
手机 mobile phone
💻 U+1F4BB
笔记本电脑 laptop

参数矩阵

参数作用示例
码位 U+XXXXXemoji 的唯一标识,用于正则过滤、去重与数据库主键👍 U+1F44D :: 点赞 thumbs up
Emoji 分区范围按码位区间快速判断某字符是否为 emoji,无需逐个枚举😀 U+1F600 :: 笑脸 grinning face
英文名称与 Unicode 标准对齐的检索键,用于搜索框、标签系统与跨平台校验🎵 U+1F3B5 :: 音符 musical note
代理对占位注意部分表内 emoji(如 ✌️ U+270C)带变体选择符,实际占两个码位✌️ U+270C :: 胜利 victory hand
语义分类按表情/手势/动物/食物/运动分组,用于表情选择器的分区布局🍕 U+1F355 :: 披萨 pizza

易错点与避坑指南

现象JS 里 emoji.length 得到 2 而不是 1,字符串截断把表情切成乱码。

原因emoji 位于 BMP 之外,用两个 UTF-16 代理码元表示,length 数的是码元不是字符。

处置用 [...str] 或 Array.from(str) 迭代字符,或按码位用 codePointAt 取值后再截断。

现象用户输入的两个「看起来一样」的 emoji 被当成两个不同的值。

原因带变体选择符的 emoji(如 ✌️ U+270C)比不带选择符的多一个 U+FE0F,字形相同但码位不同。

处置做比较或去重前先归一化,剥离 U+FE0F 变体选择符再比对。

现象数据库列长度按字符数设成 10,实际存不进一个完整表情序列。

原因utf8mb4 下一个 emoji 占 4 字节,且 varchar 长度在部分数据库里按字符计、按字节截断。

处置统一使用 utf8mb4 字符集,并为含 emoji 的列预留足够长度。

现象通知里的 emoji 在部分平台显示成方框。

原因目标字体或平台缺少该码位的字形,缺字形即渲染为豆腐块。

处置优先选用覆盖最广的基础 emoji(本表情类表内条目),并为关键通知准备文字回退。

排障路径

  1. 1查一个 emoji 的实际码位与码元长度

    node -e "const s=process.argv[1];console.log([...s].map(c=>c.codePointAt(0).toString(16)))" "👍"

    输出 1f44d 说明它是单码点;若出现两个值则是代理对或带变体选择符。

  2. 2判断字符串里是否含表内表情区间字符

    node -e "console.log(/[\u{1F300}-\u{1FAFF}]/u.test(process.argv[1]))" "hi 👍"

    true 表示落在表情区间;带 u 标志才能正确处理代理对。

命令示例

看 emoji 的长度、码点与代理对

node -e " const e = '\u{1F600}'; console.log('length', e.length, 'codePointAt', e.codePointAt(0).toString(16), 'charCodeAt', e.charCodeAt(0).toString(16)); console.log('fromCodePoint', String.fromCodePoint(0x1f600) === '\u{1F600}'); "

length 2 说明它占一个代理对;charCodeAt(0) 返回的是高 surrogate 的 0xD83D,真正码位要靠 codePointAt 才能拿到。

输出

length 2 codePointAt 1f600 charCodeAt(0) d83d
fromCodePoint true

带变体选择符的表情为何判不相等

node -e " const a = '\u{1F600}', b = '\u{1F600}\u{FE0F}'; console.log(a === b, a.codePointAt(0) === b.codePointAt(0)); console.log([...b].map(c => c.codePointAt(0).toString(16))); "

两个字符串不等,但首个码位相同。做去重时要么按码位序列比较,要么先剥掉 FE0F 这类变体选择符。

输出

false true
[ '1f600', 'fe0f' ]

用码位区间正则筛出文本里的 emoji

node -e " const re = /[\u{1F300}-\u{1FAFF}]/u; const t = 'ship \u{1F680} done\u{1F600} ok'; console.log([...t].filter(c => re.test(c)).join(' ')); console.log('count', [...t].filter(c => re.test(c)).length); "

u 标志让区间按码点解释,缺了它就会把代理对拆开匹配。展开运算符保证按码点而非 code unit 遍历。

输出

🚀 😀
count 2

确认每个 emoji 的 UTF-8 字节数

python -c " for c in ['\U0001F600', '\U0001F44D', '\u2764']: print(hex(ord(c)), len(c.encode('utf-8'))) "

补充平面区码位占 4 字节,BMP 里的符号只占 3 字节——按 4 字节为每个表情留列宽会浪费空间,按 3 字节算则会溢出。

输出

0x1f600 4
0x1f44d 4
0x2764 3

常见坑与注意事项

  • 不要用 emoji 的 length 当字符数:代理对让 length 恒为 2,截断会切出半个乱码,需要按显示宽度切就用 Intl.Segmenter。
  • 用户输入里两个「看起来一样」的表情可能码位序列不同(带不带 U+FE0F 变体选择符),去重前先归一化,否则统计会翻倍。
  • MySQL 必须用 utf8mb4 才能存补充平面码位,旧的 utf8 三字节字符集会让 U+1F600 直接写入失败。
  • 按码位区间写过滤正则时务必加 u 标志,缺少它会按 code unit 匹配,把代理对拆成两个无意义字符。
  • 数据库列宽别按「一个表情一个字符」估算:肤色修饰符与变体选择符叠加后可达十余个码元,留不出余量就会静默截断。

提示

  • Emoji 是 4 字节 UTF-8,MySQL 需要用 utf8mb4 字符集才能存储。
  • 不同系统显示的 Emoji 样式可能不同(iOS、Android、Windows 各有自己的字体)。
  • JavaScript 中可以用 String.fromCodePoint(0x1F600) 生成 Emoji。
  • 某些 Emoji 由多个 Unicode 组合(如肤色、性别),长度可能超过 2。
  • 正则匹配 Emoji 需要用 \p{Emoji} 或专门的 Emoji 正则库。

常见问题

为什么 JavaScript 里 emoji 的 length 是 2?

因为 JS 字符串按 UTF-16 code unit 计数,而 U+1F600 落在 BMP 之外,必须用代理对表示:高 surrogate 0xD83D 加低 surrogate 0xDE00,正好两个 code unit。按「用户看到的一个字符」计数要用码点遍历(展开运算符)或 Intl.Segmenter;按显示宽度截断(例如截取前 10 个字符)则必须用 Segmenter,否则会把代理对劈开得到半个乱码。

U+2764 和 U+2764 加 U+FE0F 是同一个表情吗?

不是同一个码位序列,但渲染出来通常一样。U+2764 是红心本身,U+FE0F 是变体选择符,要求渲染器采用彩色(emoji)呈现而非单色文本样式。本表里的胜利手势(U+270C)与红心都带了这个选择符。后果是:字符串去重时 2764 与 2764 FE0F 判为不等,比较码点却相等——所以做 emoji 校验要按码位遍历,而不是把原始码位值直接当唯一键。

表里的 U+2615 和 U+26BD 为什么和大多数 emoji 差得远?

因为它们占的码位不同:绝大多数表情在 U+1F300 到 U+1FAFF 的补充平面区,UTF-8 占 4 字节;而 U+2615、U+26BD 落在 BMP 的杂项符号区,UTF-8 只占 3 字节。它们在早期标准里被定义为「带 emoji 呈现的文本符号」,所以往往也要带 U+FE0F 才稳定显示成彩色。做区间过滤时若只匹配补充平面,会漏掉这一类;长度假设也不能统一按 4 字节算。

用 emoji 长度当数据库列宽会出什么问题?

会静默截断或直接写不进去。一条看似一个字符的表情可能是代理对(2 个 code unit)再叠加肤色修饰符或变体选择符,最多可达十几个码元;用 VARCHAR(10) 按字符数定义时,UTF-8 字节数还会再放大四倍。最稳的做法是按 utf8mb4 建列并把宽度放大到最坏情况的余量,或者干脆用 TEXT / JSON 列并在应用层校验,而不是依赖数据库的长度语义。

怎么快速判断一串文本里到底有几个表情?

按码点遍历后逐个测正则,而不是按 length 相除。用展开运算符把字符串拆成码点序列,再用带 u 标志的表情区间正则逐个测试并计数,得到的就是真实的表情个数。这个方法同时躲开了代理对带来的 length 虚高问题,也是给通知内容做截断前必须做的一步。

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。

由 巧匠 维护

公开更新于 2026年7月21日,内容持续校对官方文档。

联系我们

命令或描述有误?提交反馈、商务合作或产品建议都可发送邮件给我们。

联系我们