Emoji Regex Patterns: Matching Emojis in JavaScript and Python

Why Emoji Regex Is Hard

Writing a regex that correctly matches emoji is surprisingly difficult. A single visible emoji like 👨‍👩‍👧‍👦 (family) is composed of 7 Unicode code points joined by invisible characters. A regex that matches a single character will match fragments of emoji, or miss them entirely.

The root problems are:

  1. Variable length: emoji range from 1 code point (😀) to 10+ code points (complex ZWJゼロ幅接合子(ZWJ) (ZWJ)
    複数の絵文字を1つの複合絵文字に結合するために使われる不可視のUnicode文字(U+200D)。人物と物体を組み合わせた職業絵文字などに使用される。
    sequences)
  2. Surrogate pairs: in UTF-16UTF-16
    1文字あたり2または4バイトを使用する可変長Unicode符号化方式。JavaScript、Java、Windowsが内部的に使用している。
    environments (JavaScript), each emoji above U+FFFF is two code units
  3. Combining characters: variation selectors, skin tone modifiers, and ZWJ are invisible but part of the emoji
  4. Evolving standard: new emoji are added each Unicode release, so hardcoded ranges go stale

JavaScript: Using the Unicode Flag

The u flag enables Unicode mode in JavaScript regex, making . match a full code point rather than a single UTF-16 code unit.

// Without u flag: . matches one code unit (breaks emoji)
/^.$/.test('😀')   // false — emoji is 2 code units
/^.$/u.test('😀')  // true — u flag treats it as one code point

// Match any single emoji code point (basic, not sequences)
const basicEmoji = /\p{Emoji}/u;
basicEmoji.test('Hello 😀')  // true

// The v flag (ES2024) adds set operations and is stricter
const emojiV = /[\p{Emoji}--\p{Number}]/v;

Matching Full Emoji Grapheme Clusters

To match complete emoji including ZWJ sequences and skin tones, you need a pattern that handles all the components:

// Comprehensive emoji regex (covers most cases)
const emojiRegex = /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu;

// Even better: use the emoji-regex npm package
// import emojiRegex from 'emoji-regex';
// const re = emojiRegex();

// Example usage
const text = 'Hello 👋 World 🌍 from 👨‍💻';
const matches = text.match(emojiRegex);
// ['👋', '🌍', '👨‍💻']  ← note: ZWJ sequence captured as one match

The emoji-regex Package

For production use, the emoji-regex npm package by Mathias Bynens generates a regex from the Unicode data and handles all edge cases:

import emojiRegex from 'emoji-regex';

const re = emojiRegex();
const str = '💃🏽 dancing and 🚀 launching';

let match;
while ((match = re.exec(str)) !== null) {
  console.log(`Found: ${match[0]} at index ${match.index}`);
}
// Found: 💃🏽 at index 0
// Found: 🚀 at index 14

Python: The emoji Library and Regex

Python 3 handles code points natively — '😀' has length 1. But matching emoji sequences still requires care.

Using Unicode Property Escapes with regex

The built-in re module does not support Unicode property escapes. Install the regex module instead:

import regex

# Match emoji with Unicode property escapes
pattern = regex.compile(r'\p{Emoji}', regex.UNICODE)
pattern.findall('Hello 😀 World 🌍')
# ['😀', '🌍']

# Match grapheme clusters (handles ZWJ sequences)
grapheme_pattern = regex.compile(r'\X', regex.UNICODE)
grapheme_pattern.findall('👩‍💻 coding')
# ['👩‍💻', ' ', 'c', 'o', 'd', 'i', 'n', 'g']

The \X pattern matches a full Unicode grapheme cluster — the correct unit for "one visible character."

Using the emoji Library

For higher-level emoji operations, the emoji library is excellent:

import emoji

# Find all emoji in text
text = 'I love 🐍 Python and ☕ coffee'
emoji.emoji_list(text)
# [{'match_start': 7, 'match_end': 8, 'emoji': '🐍'},
#  {'match_start': 19, 'match_end': 20, 'emoji': '☕'}]

# Check if string is entirely emoji
emoji.is_emoji('😀')   # True
emoji.is_emoji('hello') # False

# Count distinct emoji
emoji.emoji_count('🐍🐍🐍')  # 3
emoji.emoji_count('🐍🐍🐍', unique=True)  # 1

Matching Specific Emoji Subsets

Flags Only

Country flags are Regional Indicator Symbol pairs (U+1F1E6–U+1F1FF):

// Match flag emoji (two regional indicator letters)
const flagRegex = /[\u{1F1E6}-\u{1F1FF}]{2}/gu;
'I am from 🇩🇪 and you from 🇺🇸'.match(flagRegex);
// ['🇩🇪', '🇺🇸']
import regex

flag_pattern = regex.compile(r'[\U0001F1E6-\U0001F1FF]{2}')
flag_pattern.findall('Visiting 🇯🇵 and 🇰🇷')
# ['🇯🇵', '🇰🇷']

Keycap Sequences

Keycaps like 0️⃣ through 9️⃣ follow the pattern: digit + U+FE0F + U+20E3:

const keycapRegex = /[0-9#*]\uFE0F\u20E3/gu;
'Press 1️⃣ or 2️⃣'.match(keycapRegex);
// ['1️⃣', '2️⃣']

Common Mistakes

Mistake 1: Using . without the u flag in JavaScript. It matches one code unit, splitting emoji.

Mistake 2: Checking str.length > 0 to detect emoji content. An emoji-only string can have .length of 8 or more.

Mistake 3: Using character class ranges like [\u0080-\uFFFF] — this misses most modern emoji above U+FFFF and produces false positives for non-emoji Unicode characters.

Mistake 4: Forgetting variation selector U+FE0F. The character ❤ (U+2764) without VS16 is a text symbol; ❤️ with U+FE0F is the emoji presentation.

Testing Your Pattern

Use our Sequence Analyzer to inspect any emoji's code points, then test your regex against it to verify full matches. Always test against ZWJ sequences, skin tone variants, and flag emoji before shipping emoji-handling code.

関連ツール

🔍 シーケンスアナライザー シーケンスアナライザー
ZWJ シーケンス、肌の色の修飾子、キーキャップシーケンス、国旗のペアを個別のコンポーネントに分解します。

用語集の項目

UTF-16 UTF-16
1文字あたり2または4バイトを使用する可変長Unicode符号化方式。JavaScript、Java、Windowsが内部的に使用している。
コードポイント コードポイント
Unicode規格で各文字に割り当てられた固有の数値。U+XXXX形式で表記される(例:😀はU+1F600)。
コード単位 コード単位
文字を符号化するための最小ビット単位。UTF-8では8ビット、UTF-16では16ビット、UTF-32では32ビット。
ゼロ幅接合子(ZWJ) (ZWJ) ゼロ幅接合子(ZWJ) (ZWJ)
複数の絵文字を1つの複合絵文字に結合するために使われる不可視のUnicode文字(U+200D)。人物と物体を組み合わせた職業絵文字などに使用される。
ユニコード ユニコード
すべての文字体系と絵文字を含む、あらゆる文字にユニークな番号を割り当てる汎用文字符号化規格。
地域インジケーター (RI) 地域インジケーター (RI)
ISO 3166-1 alpha-2コードに基づき、ペアで使用すると国旗絵文字を形成するUnicode文字(U+1F1E6からU+1F1FF)。
書記素クラスター 書記素クラスター
複数のUnicodeコードポイントで構成されていても、1つの視覚的な単位として表示されるユーザーが認識する文字。
異体字セレクタ (VS) 異体字セレクタ (VS)
文字をテキスト形式(モノクロ)で表示するかどうかを切り替えるUnicode文字。VS-15(U+FE0E)がテキスト表示、VS-16(U+FE0F)が絵文字表示を指定する。
絵文字 絵文字
「絵文字」は「えもじ」と読む日本語で「絵+文字」を意味する。デジタルコミュニケーションでアイデア・感情・物事を表現するために使われる小さなグラフィック記号。
絵文字表示 絵文字表示
文字をカラフルな絵文字グリフとして表示するデフォルトのレンダリング。本来的に絵文字として定義されているか、Variation Selector-16によって指定される。

関連ストーリー