Skip to main content
Best Emojis

Emoji pour développeurs

La plupart des bugs liés aux emoji viennent d'un seul décalage : votre code compte autre chose que ce que voit le lecteur. Un emoji famille, c'est une seule image, sept code points, 11 caractères JavaScript et 25 octets. Nous avons fait passer les regex, segmenteurs et calculs de longueur habituels sur les 3,963 emoji de la liste officielle d'Unicode, et cette page publie ce qu'ils reconnaissent réellement, pour que vous choisissiez la bonne méthode avant qu'un rapport de bug ne vous dise laquelle vous avez choisie.

3,963
emoji dans Unicode 18.0, tous testés
2,770
comptent plus d'un code point
271
ignorés par un filtre Extended_Pictographic
35
octets dans l'emoji le plus long

Un emoji, une longueur différente dans chaque langage

Chaque cellule indique ce que renvoie cette expression pour l'emoji en tête de colonne. Les résultats se répartissent en quatre groupes : unités UTF-16, code points, octets UTF-8 et graphèmes (ce que compte une personne). La colonne des graphèmes est calculée par Intl.Segmenter sur ce serveur ; un runtime avec des données Unicode plus anciennes peut donc renvoyer davantage pour les emoji les plus récents.

ExpressionCompte😀❤️👍🏽🇯🇵👩‍💻👨‍👩‍👧‍👦🧑🏻‍❤️‍💋‍🧑🏼
JavaScripts.lengthunités UTF-16224451115
JavaScript[...s].lengthcode points12223710
JavaScriptIntl.Segmentergraphèmes1111111
Pythonlen(s)code points12223710
Pythonlen(s.encode('utf-8'))octets UTF-84688112535
Javas.length()unités UTF-16224451115
Javas.codePointCount(0, s.length())code points12223710
C#s.Lengthunités UTF-16224451115
C# (.NET 5+)new StringInfo(s).LengthInTextElementsgraphèmes1111111
Golen(s)octets UTF-84688112535
Goutf8.RuneCountInString(s)code points12223710
Rusts.len()octets UTF-84688112535
Rusts.chars().count()code points12223710
Swifts.countgraphèmes1111111
Swifts.unicodeScalars.countcode points12223710
Rubys.lengthcode points12223710
Rubys.grapheme_clusters.lengthgraphèmes1111111
PHPstrlen($s)octets UTF-84688112535
PHPmb_strlen($s)code points12223710
PHPgrapheme_strlen($s)graphèmes1111111
MySQLCHAR_LENGTH(s)code points12223710
MySQLLENGTH(s)octets UTF-84688112535
SQL ServerLEN(s) on nvarcharunités UTF-16224451115

Ce qu'une coupe naïve fait à un emoji

Voici s.slice(0, n) appliqué à la famille 👨‍👩‍👧‍👦 pour chaque valeur de n. La plupart des coupes n'échouent pas bruyamment. Elles renvoient une autre famille, plus petite, et c'est ainsi que ce genre de bug part en production sans que personne ne le remarque.

Coupe à nCe qui resteCode points restants
s.slice(0, 1)�une moitié de paire de substitution (affichée comme �)0
s.slice(0, 2)👨1
s.slice(0, 3)👨‍2
s.slice(0, 4)👨‍�une moitié de paire de substitution (affichée comme �)2
s.slice(0, 5)👨‍👩3
s.slice(0, 6)👨‍👩‍4
s.slice(0, 7)👨‍👩‍�une moitié de paire de substitution (affichée comme �)4
s.slice(0, 8)👨‍👩‍👧5
s.slice(0, 9)👨‍👩‍👧‍6
s.slice(0, 10)👨‍👩‍👧‍�une moitié de paire de substitution (affichée comme �)6
s.slice(0, 11)👨‍👩‍👧‍👦7

Le drapeau qui change de pays

Les lettres d'indicateur régional s'apparient depuis le début de la chaîne. Retirez un code point au début de 🇺🇸🇯🇵 et les lettres restantes s'apparient autrement : 🇸🇯🇵. Aucune erreur, juste un autre pays.

🇺🇸🇯🇵 US + JP → 🇸🇯 SJ (Svalbard & Jan Mayen) + 🇵

Quelle regex d'emoji reconnaît quoi

Testé le 2026-10-20 sur les 3,963 emoji fully-qualified, avec Node 25.2.1, qui embarque les données d'Unicode 17.0. Un motif ne compte comme correspondance que s'il couvre l'emoji entier.

MotifCorrespondancesCe qui lui échappe
/^\p{RGI_Emoji}$/v3,944 / 3,963Tous les emoji plus récents que les données Unicode du moteur : Emoji 18.0 (19)
Intl.Segmenter3,963 / 3,963Rien sur ce runtime
/\p{Extended_Pictographic}/u3,692 / 3,963259 drapeaux et 12 keycaps, qui ne contiennent aucun code point pictographique
/^\p{Extended_Pictographic}$/u1,193 / 3,963Tout ce qui compte plus d'un code point : tons de peau, drapeaux, keycaps, séquences ZWJ et emoji avec sélecteur de style

Et celle à éviter : \p{Emoji} reconnaît aussi # * 0 1 2 3 4 5 6 7 8 9 © ®. Utilisez-la pour supprimer les emoji et vous effacerez tous les chiffres du texte.

Supprimer les emoji : ce que chaque approche laisse derrière elle

Les deux lignes ci-dessous partaient du même texte. Les restes sont invisibles dans la plupart des polices, et c'est justement pour cela qu'ils posent problème plus tard : dans la recherche, la déduplication et les limites de longueur.

Great 👍🏽 job ❤️ 👩‍💻 🇯🇵 #️⃣1

ApprocheRésultatCode points restants
Supprimer \p{Extended_Pictographic}Great 🏽 job ️ ‍ 🇯🇵 #️⃣1U+1F3FD U+FE0F U+200D U+1F1EF U+1F1F5 U+FE0F U+20E3
Supprimer \p{RGI_Emoji}Great job 1aucun

La place que prennent les emoji en base de données

Octets UTF-8 par emoji sur l'ensemble des 3,963. 30% tiennent en quatre octets ou moins ; le plus long en demande 35. Si une colonne est limitée en octets plutôt qu'en caractères, dimensionnez-la d'après ce tableau, pas d'après l'apparence du texte.

Octets UTF-8Emoji qui tiennentPart
≤ 41,19330%
≤ 82,34659%
≤ 112,42461%
≤ 173,42486%
≤ 283,86898%
≤ 353,963100%

🧑🏻‍❤️‍💋‍🧑🏼 U+1F9D1 U+1F3FB U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F9D1 U+1F3FC

Choisissez le compte qui correspond à la limite que vous appliquez

Il n'existe pas une seule bonne longueur, seulement celle qui correspond à la règle que vous appliquez. Une colonne limitée en octets a besoin d'octets UTF-8. Un champ de texte qui promet 50 caractères à un utilisateur a besoin de graphèmes, sinon quelqu'un qui tape trois drapeaux s'entendra dire qu'il en a utilisé 12. SQL Server fait exception : nvarchar(n) compte des unités UTF-16, donc 😀 occupe deux caractères d'un nvarchar mais un seul d'un varchar MySQL ou PostgreSQL, qui comptent des code points. Décidez lequel des quatre vous visez, écrivez-le dans le nom de la variable, et le reste suit.

Tronquez aux limites de graphèmes, pas aux index

Toute coupe par index peut tomber au milieu d'un emoji. En UTF-16, le pire cas est une moitié de paire de substitution, que la plupart des moteurs de rendu affichent comme un carré avec un point d'interrogation et que certains encodeurs JSON refusent purement et simplement. Avec les code points, rien ne casse visiblement, ce qui est pire : la famille perd un enfant, un ton de peau se détache et apparaît comme un carré brun, ou un drapeau devient deux lettres. La solution consiste à segmenter d'abord, puis à couper un nombre entier de graphèmes. Intl.Segmenter est présent dans tous les grands navigateurs depuis que Firefox 125 l'a livré en avril 2024, et dans Node depuis plus longtemps : l'excuse du découpeur écrit à la main ne tient plus.

Extraits prêts à copier

Courts, et sans dépendance quand le langage le permet. Chacun règle un cas tiré des tableaux ci-dessus.

Compter ce que voit le lecteur (JavaScript)

const seg = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
const visibleLength = (s) => [...seg.segment(s)].length;

visibleLength('👨‍👩‍👧‍👦 ok'); // 4, while '👨‍👩‍👧‍👦 ok'.length is 14

Tronquer sans couper un emoji (JavaScript)

function truncate(s, max, ellipsis = '…') {
  const parts = [...seg.segment(s)].map((x) => x.segment);
  return parts.length <= max ? s : parts.slice(0, max - 1).join('') + ellipsis;
}

Trouver tous les emoji, drapeaux et keycaps compris (JavaScript)

// ES2024 'v' flag: Chrome 112, Safari 17, Firefox 116, Node 20
const emoji = /\p{RGI_Emoji}/gv;
'Go 🇯🇵 #️⃣1 👍🏽'.match(emoji); // ['🇯🇵', '#️⃣', '👍🏽']

La même chose en Python, avec le module regex

import regex  # pip install regex; the built-in re has no \X

graphemes = regex.findall(r'\X', '👨‍👩‍👧‍👦 ok')
len(graphemes)  # 4, while len('👨‍👩‍👧‍👦 ok') is 10

Des colonnes qui acceptent tous les emoji

-- MySQL: utf8mb4 on the column AND the connection
CREATE TABLE posts (body VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci);
SET NAMES utf8mb4;

-- PostgreSQL: any UTF8 database already stores every emoji
-- SQL Server: use nvarchar, and remember LEN() counts UTF-16 units

Pourquoi aucune regex n'est jamais terminée

Chaque propriété d'emoji d'un moteur de regex provient de données Unicode compilées dans ce moteur : un motif n'est donc à jour que dans la mesure où le runtime qui l'exécute l'est. Notre propre test le montre : \p{RGI_Emoji} a reconnu 3,944 emoji sur 3,963, car les 19 séquences les plus récentes ne figurent pas encore dans les tables Unicode 17.0 de Node 25.2.1. Le même code les reconnaîtra après une mise à jour du runtime, et un utilisateur sur un navigateur plus ancien continuera de les rater. Si une vérification doit accepter les nouveaux emoji dès leur sortie, travaillez sur la structure (Extended_Pictographic plus modificateurs, joiners et sélecteurs) ou sur les graphèmes, et n'utilisez la propriété que là où un faux négatif est sans conséquence.

Un même emoji peut être stocké de trois façons

Unicode recense 3,963 emoji fully-qualified, plus 1,029 formes minimally-qualified et 243 formes unqualified des mêmes images, surtout les versions sans le sélecteur de style U+FE0F. ❤ et ❤️ ont le même aspect dans de nombreuses applications mais sont des chaînes différentes : un contrôle d'unicité, un compteur de réactions ou un index de recherche les traite comme deux choses distinctes. La normalisation Unicode n'y change rien : NFC et NFKC laissent les sélecteurs de variante intacts. Si vous comparez ou dédupliquez des emoji, choisissez une forme (fully-qualified est le choix sûr) et convertissez à l'entrée à l'aide de la liste de qualification, plutôt que de retirer tous les U+FE0F, ce qui casserait aussi des keycaps comme 1️⃣.

Convertisseur emoji vers UnicodeToutes les séquences ZWJ, avec leur tailleCompteur de caractères qui compte correctement les emojiGlossaire des emoji

Les questions que se posent les développeurs sur les emoji

Pourquoi la longueur d'un emoji vaut-elle 2 en JavaScript ?

Les chaînes JavaScript sont en UTF-16, et tout caractère au-delà de U+FFFF occupe deux unités de 16 bits, une paire de substitution. Presque tous les emoji se trouvent au-delà de U+FFFF, si bien que même un simple 😀 a un .length de 2. Utilisez [...str].length pour les code points ou Intl.Segmenter pour ce que voit le lecteur.

Quelle est la meilleure regex pour reconnaître les emoji ?

En JavaScript moderne, /\p{RGI_Emoji}/v reconnaît les séquences d'emoji complètes, drapeaux et keycaps compris, mais seulement jusqu'à la version d'Unicode que connaît le moteur. \p{Extended_Pictographic} rate les drapeaux et les keycaps, et \p{Emoji} reconnaît à tort les chiffres, # et *.

Comment compter un emoji comme un seul caractère ?

Comptez les clusters de graphèmes. En JavaScript, utilisez Intl.Segmenter avec granularity grapheme ; en Swift, String.count le fait déjà ; en Python, utilisez \X du module tiers regex ; en PHP, grapheme_strlen de l'extension intl.

Combien d'octets faut-il pour stocker un emoji ?

En UTF-8, entre 3 et 35 octets. Un emoji d'un seul code point au-delà de U+FFFF en prend 4. Les tons de peau, les drapeaux et les séquences jointes s'additionnent : dans notre test, 59% de tous les emoji tiennent en 8 octets, et le plus long, un bisou avec deux tons de peau, en prend 35.

Pourquoi mon emoji devient-il ???? dans la base de données ?

La colonne ou la connexion utilise un jeu de caractères qui ne peut pas contenir de caractères sur quatre octets, généralement l'ancien utf8 de MySQL. Passez à la fois la table et la connexion en utf8mb4. Notre page du convertisseur Unicode détaille l'instruction ALTER TABLE exacte.