Compter des caractères face à une limite fixée par quelqu'un d'autre
Publié le 10/08/2026 · 14 min de lecture · Outils texte & langage
Daniel Okonkwo — Développeur front-end et rédacteur Tech chez Allin
Performance web · Formats de fichiers
Vérifié à partir de 4 sources
« Caractère » ne désigne pas une seule chose, et celui qui a écrit la limite a tranché sans te le dire. Le compteur de fréquence de cette page parcourt la chaîne avec un itérateur de points de code : il compte donc des points de code Unicode. Colle-lui l'émoji famille et il renvoie cinq lignes dont la somme fait sept : quatre lignes pour les quatre personnes, et une ligne pour quelque chose qui ne s'affiche pas du tout — le liant sans chasse, avec un compte de 3. Cette même chaîne vaut 1 grappe de graphèmes, 7 points de code, 11 unités UTF-16 et 25 octets UTF-8. Ces quatre nombres sont ce que quatre systèmes différents appellent sa longueur : un champ annonçant 500 caractères en accepte 500 s'il compte des graphèmes, 71 s'il compte des points de code, 45 s'il utilise le .length de JavaScript ou le .length() de Java, et 20 si la colonne derrière fait 500 octets. L'outil n'affiche aucun total ; tu additionnes la colonne toi-même, et ses réglages par défaut ignorent les espaces et la casse, d'où « Merci beaucoup ! » qui donne 11 lignes totalisant 14 et non 16 caractères. Le SMS est plus dur. Le protocole transporte 140 octets, soit 160 caractères de l'alphabet GSM 7 bits ou 70 en UCS-2, et 153 et 67 dès que les messages sont concaténés. Un seul caractère hors de la table 7 bits fait basculer tout le message : une apostrophe courbe suffit, n'importe quel émoji suffit, et les á í ó ú espagnols comme les ã õ portugais aussi, car la table par défaut ne les contient tout simplement pas. Les méta-descriptions, elles, ne se comptent pas : les extraits sont coupés à la largeur rendue, pas au caractère.
Un émoji vaut 1 caractère, ou 7, ou 11, ou 25, selon qui compte. Lequel ton formulaire, ta base et ta passerelle SMS veulent dire — et un test d'un seul collage pour savoir auquel tu as affaire.
Quatre nombres pour un seul émoji
Prends l'émoji famille composé d'un homme, d'une femme, d'une fille et d'un garçon. C'est une seule chose à l'écran, une seule frappe de Retour arrière l'efface, et le curseur le franchit en un seul pas. En dessous, ce sont quatre émojis de personnes séparés par trois copies d'un caractère de contrôle invisible, U+200D, le liant sans chasse. Mesurée de quatre façons, cette chaîne fait 1 grappe de graphèmes, 7 points de code, 11 unités UTF-16 et 25 octets UTF-8. Aucun de ces nombres n'est faux ; ils répondent à quatre questions différentes.
La grappe de graphèmes, c'est le caractère tel que le perçoit l'utilisateur, et Unicode définit les frontières entre elles dans une annexe technique, l'UAX n° 29, précisément parce que « ce qu'un lecteur considère comme un caractère » n'est pas assez évident pour être laissé à chaque programme. Le point de code, c'est l'entrée numérotée du catalogue Unicode. L'unité UTF-16, c'est un emplacement de seize bits, et tout ce qui dépasse U+FFFF en réclame deux — c'est le nombre que rendent JavaScript, Java et C# quand tu demandes la longueur d'une chaîne. L'octet UTF-8, c'est ce qui circule vraiment sur le réseau et occupe une colonne de base de données.
Ce que compte cet outil, exactement
Le compteur de fréquence parcourt l'entrée avec une boucle for-of, qui en JavaScript avance par points de code et non par unités de seize bits. Il compte donc des points de code, et on peut le voir faire. Colle l'émoji famille avec les réglages par défaut et la sortie fait cinq lignes : une ligne d'apparence vide avec le compte 3, puis quatre lignes à 1 chacune. La ligne vide, c'est le liant sans chasse. Additionne la colonne et tu obtiens 7, c'est-à-dire le nombre de points de code, pas le 1 que tu répondrais si on te demandait combien de caractères tu as collés.
Deux réglages par défaut modifient le calcul avant que tu ne le voies. « Ignorer les espaces » est activé, donc les espaces n'apparaissent jamais dans la table : « Merci beaucoup ! » fait 16 caractères mais produit 11 lignes totalisant 14, les deux espaces ayant sauté. « Ignorer la casse » est activé aussi et fusionne les paires — ce que l'on veut le plus souvent, et qui produit parfois quelque chose d'étrange. Le İ majuscule turc se met en minuscule en un i suivi d'un point combinant distinct, si bien que la table gagne une ligne dont la clé fait deux points de code. L'outil n'a jamais prétendu que la clé de ligne était un caractère unique ; c'est ce que la conversion en minuscule a produit.
Et il n'affiche pas de total. La sortie est un tableau à deux colonnes, caractère et compte, trié par compte puis alphabétiquement, et le nombre que tu cherchais est probablement la somme de la seconde colonne. Si tu veux les quatre comptes côte à côte sans calcul, le compteur d'octets UTF-8 du site affiche graphèmes, points de code, octets UTF-8, unités UTF-16, mots et lignes d'un seul coup — il existe justement parce que ces nombres divergent, et son propre commentaire le dit.
Le test d'un seul collage qui révèle à quel compteur tu as affaire
Colle un seul émoji famille dans le champ muni du compteur, et lis le compteur. S'il affiche 1, il compte des grappes de graphèmes. S'il affiche 7, des points de code. S'il affiche 11, il utilise la longueur de chaîne native du langage, donc des unités UTF-16 — JavaScript, Java ou C#. S'il affiche 25, il compte des octets UTF-8, et la limite est en réalité une limite d'octets. Quatre réponses possibles, quatre systèmes différents derrière le champ, et le test tient en un collage.
Le test a une seconde moitié, et elle compte davantage : le compteur que tu vois dans le navigateur n'est pas forcément celui qui décide. Un compteur côté client, c'est presque toujours le .length de JavaScript, alors que le refus à l'envoi vient d'un serveur, d'une définition de colonne ou d'une API en aval qui a sa propre idée. Si le champ te laisse taper 500 et que l'enregistrement échoue à 480, les deux bouts comptent différemment et c'est le plus court qui gagne. Tape le texte, enregistre, recharge la page et regarde ce qui revient — une troncature se voit plus facilement qu'elle ne se prévoit.
SMS : 160 caractères, ou 70, et c'est une apostrophe qui tranche
Le service de messages courts transporte jusqu'à 140 octets de données utilisateur. Empile-les avec l'alphabet GSM 7 bits par défaut et tu loges 160 caractères ; encode en UCS-2, deux octets par unité, et tu en loges 70. Quand un message est trop long il est découpé, et chaque partie cède de la place à un petit en-tête qui dit quelle partie elle est : il reste 153 caractères 7 bits ou 67 unités UCS-2 par segment. Rien de tout cela n'est négociable, et toutes les grilles tarifaires du SMS en nombre sont bâties là-dessus.
L'intéressant, c'est ce que contient cette table 7 bits, car un seul caractère absent fait basculer tout le message en UCS-2 et divise la capacité par plus de deux. La table contient un jeu d'accents généreux — è é ù ì ò à ä ö ü ñ å æ ø ß, plus Ä Ö Ü Ñ É Å Æ Ø Ç — ainsi que ¡ ¿ § et quelques symboles monétaires. Elle ne contient pas á, í, ó ni ú, et pas non plus ã ni õ. Un message espagnol contenant « está » ou « aquí », ou un message portugais contenant « não », est donc un message de 70 caractères et non de 160, et rien à l'écran ne le dit à l'expéditeur.
La spécification l'avait anticipé et définit des tables nationales — l'espagnol a une table à décalage simple, le portugais en a une à décalage simple et une à décalage verrouillé. Un caractère à décalage simple coûte deux de tes emplacements 7 bits au lieu d'un, et les deux bouts doivent implémenter le mécanisme. En pratique, la plupart des passerelles n'essaient pas et basculent en UCS-2. Ce même mécanisme d'échappement explique qu'un petit ensemble de symboles courants coûte déjà deux emplacements chacun dans un message ordinaire : l'accent circonflexe seul, les accolades, les crochets, la barre oblique inverse, le tilde, la barre verticale et le signe euro vivent dans la table d'extension, pas dans la principale. Et l'apostrophe typographique que ton traitement de texte a insérée quand tu en tapais une ordinaire n'est dans aucune des deux.
La méta-description se mesure en pixels, pas en caractères
Toutes les check-lists SEO donnent une fourchette de caractères pour la méta-description. La documentation de Google n'en donne aucune : elle dit qu'il n'y a pas de limite de longueur, que l'extrait est produit à partir de la page et parfois de la description, et que les extraits sont rognés pour tenir dans le résultat. « Tenir » est affaire de largeur rendue : une description pleine de lettres larges est coupée plus tôt qu'une autre de même longueur en caractères composée de lettres étroites, et le résultat mobile dispose de moins de place que le résultat sur ordinateur.
La conséquence pratique n'est pas d'abandonner un budget de caractères, mais de cesser de le prendre pour une règle. Mets ce qui doit survivre dans la première moitié de la phrase, puis vérifie le résultat réel plutôt que le décompte. Et sache que Google réécrit souvent la description entièrement quand il juge que le contenu de la page répond mieux à la requête — une description tronquée que tu n'as jamais écrite est un problème différent d'une description tronquée que tu as écrite.
Deux graphies du même mot, deux longueurs
Un dernier piège n'a rien à voir avec les émojis. La lettre é peut être un point de code, U+00E9, ou deux : un e simple suivi d'un accent aigu combinant. Ils sont identiques à l'œil, ils veulent dire la même chose, et ils n'ont pas la même longueur — 1 point de code et 2 octets contre 2 points de code et 3 octets. La plupart des claviers produisent le premier ; certains systèmes, certains scanners et beaucoup de texte copié-collé produisent le second. Passe la forme décomposée dans le compteur de fréquence et elle ressort en deux lignes, dont l'une est un accent nu posé sur rien.
Si un contrôle de longueur échoue sur un texte qui a l'air de la bonne longueur, c'est la première chose à tester. Normaliser vers la forme composée avant de compter règle le problème, et c'est un appel unique dans tous les langages livrés avec une bibliothèque Unicode. Fais-le avant de compter, avant de stocker, et avant de comparer deux chaînes pour l'égalité — le même mot dans deux formes de normalisation n'est égal à lui-même dans aucune comparaison d'octets.
| Unité de comptage | L'émoji famille compte pour | Où tu la rencontres | Combien tiennent sous « 500 caractères » |
|---|---|---|---|
| Grappes de graphèmes (UAX n° 29) | 1 | Le String.count de Swift ; une frappe de Retour arrière ; la première ligne du compteur d'octets UTF-8 | 500 |
| Points de code Unicode | 7 — quatre personnes plus trois liants | Le len() de Python 3 ; les runes de Go ; le compteur de fréquence de cette page | 71 |
| Unités de code UTF-16 | 11 | Le .length de JavaScript, le .length() de Java, le .Length de C# — la plupart des compteurs de formulaire côté navigateur | 45 |
| Octets UTF-8 | 25 | Le len() de Go ; une colonne ou un en-tête mesurés en octets | 20 |
| Unités UCS-2 dans un segment SMS | 11 | Un segment unique de 70 unités, ou 67 dès que les messages sont concaténés | 6 par segment — le septième démarre un autre message |
Questions fréquentes
- Pourquoi la table de fréquence a-t-elle une ligne vide ?
- Parce qu'un caractère qui ne s'affiche pas reste un caractère, et le compteur le rapporte honnêtement. Dans l'émoji famille, cette ligne est U+200D, le liant sans chasse, qui apparaît trois fois : c'est lui qui colle les quatre personnes en une seule image. Les sélecteurs de variante se comportent pareil — le petit U+FE0F qui transforme un symbole monochrome en émoji couleur est invisible et compté. Une ligne vide avec un nombre à côté, c'est l'outil qui te dit que ton texte contient quelque chose que tu ne vois pas, ce qui est précisément ce qu'il faut savoir avant de le coller dans un champ à limite.
- Un seul émoji réduit-il vraiment mon SMS de moitié ?
- Plus que de moitié. Un message est encodé dans un seul alphabet de bout en bout : un caractère hors de la table GSM 7 bits force donc tout le message en UCS-2, et la capacité tombe de 160 caractères à 70. C'est pire pour les émojis : tout ce qui dépasse U+FFFF prend deux unités UCS-2, si bien qu'un simple visage souriant coûte deux de tes 70 et l'émoji famille en coûte onze. Six de ces émojis et un mot ne tiendront pas dans un seul segment. Si ta facture de SMS en nombre a bondi sans que le texte s'allonge, cherche une apostrophe courbe ou un accent absent de la table avant de chercher ailleurs.
- Mon formulaire annonce 500 caractères. De quels 500 s'agit-il ?
- Teste plutôt que de deviner. Colle un émoji famille et lis le compteur : 1 signifie grappes de graphèmes, 7 points de code, 11 unités UTF-16, 25 octets UTF-8. En ASCII pur les quatre coïncident, et c'est pourquoi l'écart n'apparaît que le jour où un utilisateur réel colle un nom accentué ou un émoji dans le champ. Si le formulaire est à toi, compte des grappes de graphèmes pour le nombre affiché et valide contre ce que la couche de stockage impose réellement, puis fixe la limite visible au plus petit des deux. Sinon, suppose la réponse la plus petite possible et garde de la marge.
- Un VARCHAR(500) en base de données, c'est cinq cents octets ou cinq cents caractères ?
- Dans les bases relationnelles courantes, la longueur déclarée est en caractères, pas en octets — mais les limites qui l'entourent sont en octets, et c'est là qu'on se fait prendre. Une ligne a une taille maximale en octets, un index a une taille de clé maximale en octets, et un encodage à quatre octets par caractère multiplie les deux. Résultat : la colonne accepte tes 500 caractères et l'index refuse d'être créé. Les limites en octets sont plus fréquentes hors de la base : valeurs d'en-têtes HTTP, charges de files de messages, clés de stockage objet et quantité d'API tierces sont spécifiées en octets. Quand la documentation dit octets, compte des octets.
- Combien de caractères doit faire une méta-description ?
- Il n'existe aucun nombre documenté, et celui qu'on t'a donné a été mesuré sur des résultats de recherche, pas publié comme une règle. La consigne de Google est que les descriptions n'ont pas de limite de longueur, que les extraits sont tirés de la page autant que de la description, et qu'ils sont rognés pour tenir — « tenir » étant affaire de largeur rendue dans une mise en page qui diffère entre téléphone et ordinateur. La bonne habitude est de charger le début : mets l'argument, le chiffre ou l'élément différenciant dans la première proposition, et considère la suite comme sacrifiable. Regarde ensuite le résultat réel dans une vraie recherche et ajuste sur ce que tu vois.
Articles qui pourraient t'intéresser
Tous les guides →Outils similaires
Ceci décrit ce que font ces outils de texte aujourd'hui, vérifié en exécutant leurs propres fonctions sur les entrées exactes citées ici. Quand un outil se trompe sur un cas, c'est écrit plutôt que lissé, parce qu'un outil imprévisible est pire qu'un outil dont on connaît les limites. Rien ici n'est une règle qu'un outil serait tenu de suivre : la capitalisation, le comptage de caractères et la numérotation des lignes sont des conventions, et ces conventions varient selon la langue, le guide de style et le programme qui se trouve à l'autre bout. Avant de passer l'un d'eux sur un texte que tu ne pourras pas retaper, passe d'abord sur une copie et compare les deux bouts.
Sources
- Unicode Consortium — UAX #29, Unicode Text Segmentation — the grapheme cluster boundary rules that define a user-perceived character, including the treatment of zero-width joiners, variation selectors and emoji modifier sequences
- ETSI / 3GPP — TS 123 038 (3GPP TS 23.038) — the GSM 7-bit default alphabet table in clause 6.2.1, its escape-driven extension table in 6.2.1.1 (which holds the caret, braces, brackets, backslash, tilde, vertical bar and euro sign), and the national language single- and locking-shift tables for Spanish and Portuguese in 6.2.1.2 and Annex A
- ETSI / 3GPP — TS 123 040 (3GPP TS 23.040) — the transfer of short messages: the user data of an SM MT or SM MO carries up to 140 octets, which is what yields 160 seven-bit characters or 70 UCS-2 units per single message
- Google Search Central — Control your snippets in search results — no documented character limit for a description; snippets are generated from the page and from the description and are trimmed to fit the result
Tu as repéré une erreur dans cet article ?