This article is not available in your language yet. Showing the zh-CN version.

Emoji 搜索与使用指南:从 Unicode 编码到跨平台兼容的完整攻略

Text(Updated Jun 2, 2026)

Emoji 的 Unicode 编码

编码范围

范围 Unicode 块 示例
U+1F600 - U+1F64F Emoticons 😀😁😂
U+1F300 - U+1F5FF Misc Symbols & Pictographs 🎨🌟🌀
U+1F680 - U+1F6FF Transport & Map 🚀🚗🚲
U+1F900 - U+1F9FF Supplemental Symbols & Pictographs 🤖🦊🦁
U+1FA00 - U+1FA6F Chess Symbols 🪀🪁🪂
U+1FA70 - U+1FAFF Symbols & Pictographs Extended-A 🪩🪫🪬

编码表示法

// Unicode 码点
console.log('\u{1F600}');  // 😀
console.log('\u{1F680}');  // 🚀

// 码点查询
console.log('😀'.codePointAt(0).toString(16));  // "1f600"

// 从码点创建
String.fromCodePoint(0x1F600);  // "😀"
String.fromCodePoint(0x1F680);  // "🚀"

UTF-8 编码长度

// Emoji 在 UTF-8 中占 4 字节
new TextEncoder().encode('😀').length;  // 4

// 但 .length 返回 2(代理对)
'😀'.length;  // 2

// 正确计算字符数
[...'😀😁😂'].length;  // 3

肤色修饰符

5 种肤色

U+1F3FB  🏻  浅肤色 (Light Skin Tone)
U+1F3FC  🏼  中浅肤色 (Medium-Light)
U+1F3FD  🏽  中等肤色 (Medium)
U+1F3FE  🏾  中深肤色 (Medium-Dark)
U+1F3FF  🏿  深肤色 (Dark)

组合方式

基础 Emoji + 肤色修饰符 = 带肤色的 Emoji

👨 + 🏽 = 👨🏽
👋 + 🏿 = 👋🏿
// JavaScript 组合
const base = '\u{1F468}';  // 👨
const modifier = '\u{1F3FD}';  // 🏽
const result = base + modifier;  // 👨🏽

// 拆解
[...'👨🏽'];  // ['👨', '🏽']

零宽连接符(ZWJ)序列

ZWJ(U+200D)将多个 Emoji 组合为一个:

👨 + ZWJ + 🏭 = 👨‍🏭  (男工厂工人)
👩 + ZWJ + 💻 = 👩‍💻  (女技术员)
👨 + ZWJ + ❤️ + ZWJ + 👨 = 👨‍❤️‍👨  (男同性情侣)

家庭组合

👨 + ZWJ + 👩 + ZWJ + 👦 = 👨‍👩‍👦  (一家三口)
👨 + ZWJ + 👨 + ZWJ + 👧 = 👨‍👨‍👧  (两个爸爸和女儿)

国旗组合

🇨 + 🇭 = 🇨🇭  (瑞士国旗)
🇯 + 🇵 = 🇯🇵  (日本国旗)
🇨 + 🇳 = 🇨🇳  (中国国旗)

国旗 Emoji 由两个区域指示符号(Regional Indicator)组成。


跨平台显示差异

Emoji Apple Google Microsoft Samsung Twitter
😀 😁风格 😁风格 😁风格 😁风格 😁风格
🔫 水枪 水枪 真枪 水枪 水枪

同一个 Emoji 在不同平台外观不同,但 Unicode 码点相同。

避免误解的建议

  1. 避免有歧义的 Emoji:🔫(枪/水枪)、🍆(蔬菜/暗示)
  2. 测试多平台显示:用 Emoji 搜索工具 查看不同平台渲染
  3. 专业场景少用:正式邮件/文档中避免使用
  4. 组合序列注意兼容:ZWJ 序列在旧系统可能显示为多个独立 Emoji

在代码中使用 Emoji

HTML

<!-- 直接使用 -->
<p>欢迎使用 🚀</p>

<!-- Unicode 转义 -->
<p>欢迎使用 &#x1F680;</p>

<!-- CSS content -->
<style>
  .icon::before { content: '\1F680'; }
</style>

JavaScript

// 直接使用(推荐)
const rocket = '🚀';

// Unicode 转义
const rocket = '\u{1F680}';

// 在字符串中
const message = `部署成功 ${rocket}`;

// 作为对象键(不推荐,但可以)
const icons = { '🚀': 'rocket', '🎨': 'art' };

Python

# 直接使用
rocket = '🚀'

# Unicode 转义
rocket = '\U0001F680'

# 在 f-string 中
message = f'部署成功 {rocket}'

数据库存储

-- MySQL:需要 utf8mb4 字符集
CREATE TABLE messages (
  content VARCHAR(500) CHARACTER SET utf8mb4
);

-- ❌ utf8 字符集无法存储 Emoji
-- ✅ utf8mb4 字符集可以存储 Emoji

使用工具库搜索 Emoji

  1. 打开 Emoji 搜索工具
  2. 输入关键词(中文或英文)如"开心"
  3. 查看匹配的 Emoji 列表
  4. 点击复制到剪贴板
  5. 支持按分类浏览

搜索示例

关键词 结果
开心 😄😁😆😊🥰
火箭 🚀🚁🛸
🐱🐈🐈‍⬛
食物 🍕🍔🍜🍣🍰
工作 💼💻📊📋✏️

Emoji 正则表达式

匹配所有 Emoji

// Emoji 正则(简化版)
const emojiRegex = /\p{Emoji_Presentation}/gu;

// 更完整的版本(包含修饰符和 ZWJ 序列)
const fullEmojiRegex = /\p{Extended_Pictographic}(\u{FE0F})?(\u{1F3FB}-\u{1F3FF})?(\u{200D}\p{Extended_Pictographic}(\u{FE0F})?(\u{1F3FB}-\u{1F3FF})?)*/gu;

// 使用
const text = 'Hello 😀 World 🚀';
const emojis = text.match(fullEmojiRegex);
// ["😀", "🚀"]

移除文本中的 Emoji

function removeEmoji(text: string): string {
  return text.replace(/\p{Emoji_Presentation}/gu, '');
}

removeEmoji('Hello 😀 World 🚀');  // "Hello  World "

统计 Emoji 数量

function countEmoji(text: string): number {
  const matches = text.match(/\p{Emoji_Presentation}/gu);
  return matches ? matches.length : 0;
}

常见问题

为什么 Emoji 显示为方框 □?

  • 字体不支持:系统缺少 Emoji 字体
  • 字符集错误:数据库/文件用了 UTF-8 而非 UTF-8MB4
  • 版本过旧:新 Emoji 需要较新的系统版本

Emoji 的 .length 为什么不是 1?

'😀'.length          // 2(代理对)
'👨🏽'.length         // 4(基础 + 修饰符,各占 2)
'👨‍👩‍👦'.length         // 8(3个Emoji + 2个ZWJ)
[...'👨‍👩‍👦'].length     // 5(正确拆解)

// 安全的字符串长度
function safeLength(str: string): number {
  return [...str].length;
}

如何获取最新 Emoji?

Emoji 每年更新一次(Unicode 版本更新),新 Emoji 需要:

  • 操作系统更新(iOS/Android/Windows)
  • 浏览器更新
  • 字体更新(Noto Color Emoji)

总结

Emoji 是 Unicode 标准的一部分,理解其编码原理(码点、修饰符、ZWJ 序列)有助于正确处理跨平台兼容问题。核心要点:utf8mb4 存储数据库、用 [...str] 计算字符数、注意跨平台显示差异。工具库的 Emoji 搜索工具 让你快速找到需要的 Emoji。

#Emoji#表情符号#Unicode#搜索#教程