Aller au contenu
Allin

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

Daniel OkonkwoDéveloppeur front-end et rédacteur Tech chez Allin

Performance web · Formats de fichiers

Vérifié à partir de 4 sources

Voir le profil
En bref

« 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.

Un émoji famille passé dans cinq compteurs, avec le nombre que chacun annonce
Unité de comptageL'émoji famille compte pourOù tu la rencontresCombien tiennent sous « 500 caractères »
Grappes de graphèmes (UAX n° 29)1Le String.count de Swift ; une frappe de Retour arrière ; la première ligne du compteur d'octets UTF-8500
Points de code Unicode7 — quatre personnes plus trois liantsLe len() de Python 3 ; les runes de Go ; le compteur de fréquence de cette page71
Unités de code UTF-1611Le .length de JavaScript, le .length() de Java, le .Length de C# — la plupart des compteurs de formulaire côté navigateur45
Octets UTF-825Le len() de Go ; une colonne ou un en-tête mesurés en octets20
Unités UCS-2 dans un segment SMS11Un segment unique de 70 unités, ou 67 dès que les messages sont concaténés6 par segment — le septième démarre un autre message
Compteur de fréquence des caractèresCompte combien de fois chaque caractère apparaît dans ton texte.Essayer l'outil

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
ExplicationDétecter la langue d'un texte, et pourquoi les textes courts échouentMesuré, pas affirmé : 90 phrases courtes réelles dans six langues, aucune refusée et 68 justes — 76 %, tombant à 64 % en dessous de seize lettres. Quatre des réponses fausses sont revenues avec 100 % de confiance.ExplicationCe que mesurent réellement les scores de lisibilité (et les trois choses qu'ils ne voient pas)Le Flesch Reading Ease et le niveau Flesch-Kincaid comptent des syllabes et des longueurs de phrase. Rien d'autre. Les deux formules en entier, un passage noté de bout en bout, et l'astuce de la virgule qui offre 3,9 niveaux scolaires sans changer un mot.ExplicationFréquence des mots et loi de Zipf : nous avons compté six livres en six langues et ajusté la penteLe mot de rang n apparaît environ 1/n fois moins que le premier. Nous avons compté six livres du domaine public, imprimé rang × fréquence, ajusté log fréquence contre log rang, et obtenu des pentes entre -1,02 et -1,08 dans les six langues — et les deux endroits où la loi casse.ExplicationCompteur de mots : temps de lecture et limitesUn compte de mots, ce sont les mots séparés par des espaces. Voici comment il se compte, pourquoi des limites existent, comment il se traduit en pages et temps de lecture, et quand ce sont les caractères qui comptent.ExplicationCasse de phrase et casse de titre : les règles changent selon la langueLa casse de titre anglaise a trois seuils différents selon le guide de style. Le français, l'espagnol, le portugais et l'italien n'en ont aucun. L'allemand capitalise chaque nom. L'outil n'en sait rien — voici exactement ce qu'il fait.ExplicationOù une ligne peut se couper : l'algorithme Unicode derrière chaque paragraphe justifié« Couper aux espaces » échoue dans la plupart des systèmes d'écriture. UAX #14 donne à chaque caractère une classe de coupure ; nous avons cherché les nôtres dans Unicode 17.0.0 et exécuté une implémentation conforme sur espaces insécables, traits d'union conditionnels, espaces de largeur nulle, URL, japonais et thaï.

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

Tu as repéré une erreur dans cet article ?