Longueur de texte
Comptez un texte de cinq façons à la fois : caractères à l’œil, points de code (len() de Python), unités UTF-16 (.length de JavaScript), mots et lignes.
Pourquoi « quelle est la longueur de ce texte ? » a plusieurs réponses
Cela semble une question triviale, mais la longueur d’un texte dépend entièrement de ce que vous comptez. Une personne compte les caractères qu’elle voit. Une base de données compte l’espace de stockage qu’occupe une valeur. JavaScript compte encore autre chose. Quand ces nombres divergent — et c’est souvent le cas pour les emojis, les lettres accentuées et les écritures non latines — une seule « longueur » est trompeuse. Cet outil affiche cinq mesures utiles côte à côte pour que vous choisissiez celle qui compte dans votre cas.
Les cinq mesures expliquées
- Caractères (graphèmes) : ce qu’un humain perçoit comme un caractère. Un emoji de famille comme 👨👩👧, ou une lettre avec un accent combinant, compte pour un — c’est le décompte qui correspond « à l’œil ».
- Points de code (code points) : le nombre de valeurs scalaires Unicode. Un seul caractère visible peut être formé de plusieurs points de code assemblés, si bien que ce nombre est souvent plus élevé que celui des graphèmes.
- Unités UTF-16 : la valeur que JavaScript renvoie via la propriété .length d’une chaîne. Les caractères hors du Plan multilingue de base (la plupart des emojis) occupent deux unités UTF-16 chacun.
- Mots : le nombre de jetons de type mot, détectés de façon compatible Unicode plutôt qu’en découpant naïvement sur les espaces.
- Lignes : le nombre de lignes, en comptant chaque saut de ligne.
Pourquoi les emojis et les accents cassent le comptage naïf
Le texte moderne est construit avec Unicode, qui représente de nombreux caractères visibles comme des séquences plutôt que des unités uniques. Un emoji de drapeau, c’est deux symboles indicateurs régionaux. Un emoji de famille, c’est plusieurs figures reliées par des caractères invisibles de « liaison de largeur nulle ». Un é accentué peut être un seul point de code, ou un e simple suivi d’un accent combinant. Chacun ressemble à un caractère mais peut compter pour deux, trois ou plus selon la mesure. C’est précisément pourquoi compter à la main, ou se fier à un seul nombre, mène à des bugs.
Quel décompte utiliser ?
- Limites de caractères vues par les gens (une bio, un champ de type tweet, un aperçu SMS) : utilisez Caractères (graphèmes), car cela correspond à ce que compte l’utilisateur.
- Manipulation de chaînes en JavaScript, indexation ou découpage : utilisez les unités UTF-16, puisque c’est sur elles que reposent .length et les index de chaîne.
- Tailles de colonnes de base de données : vérifiez si votre colonne se mesure en caractères ou en octets — beaucoup sont limitées en octets, et les octets UTF-8 diffèrent encore de tous ces décomptes.
- Comptes de mots ou de lignes pour les éditeurs et la lisibilité : utilisez les mesures Mots et Lignes.
Ce que Python et JavaScript appellent chacun la longueur
Deux des cinq décomptes ci-dessus sont ceux pour lesquels on arrive ici, et ils appartiennent à des langages différents. len() en Python et .length en JavaScript sont tous deux présentés comme la longueur d’une chaîne, et dès qu’on sort de l’ASCII simple, ils répondent différemment pour le même texte au même instant. Aucun des deux n’a tort : ils comptent des unités différentes, et les deux cases sont affichées ci-dessus pour que l’écart se lise au lieu de se deviner.
- Python : len() renvoie le nombre de points de code Unicode, car une chaîne en Python 3 est une suite de points de code. Lisez la case « Points de code » : c’est le nombre que len() vous donnera.
- JavaScript : .length renvoie le nombre d’unités de code UTF-16, car une chaîne JavaScript est stockée en UTF-16. Lisez la case « Unités UTF-16 ». Array.from(text).length parcourt en revanche la chaîne point de code par point de code, et rejoint donc Python.
- Aucun des deux ne compte ce que vous voyez. La case « Caractères » est le décompte de graphèmes, et aucune longueur intégrée de ces langages ne la produit : JavaScript a besoin d’Intl.Segmenter et Python d’un paquet tiers. Si la limite que vous imposez est une limite qu’une personne va lire, c’est cette case qu’il vous faut.
- Mots et Lignes n’appartiennent pas davantage à l’un ou à l’autre. Les deux peuvent les approcher en découpant sur les espaces et sur les sauts de ligne, et les deux s’écartent des décomptes affichés ici, qui sont compatibles Unicode — sur un texte écrit sans espaces, sur la ponctuation et sur un saut de ligne qui termine le texte.
L’exemple derrière Charger un exemple est le moyen le plus rapide de voir l’écart. Son emoji de famille vaut un caractère pour un lecteur, cinq points de code pour Python et huit unités UTF-16 pour JavaScript : trois de ces cinq points de code sont hors du Plan multilingue de base et coûtent deux unités chacun, et les deux liaisons invisibles entre eux une chacune. Un champ où l’on peut écrire vingt caractères en contient donc bien vingt à l’œil, tandis qu’une vérification naïve écrite dans l’un ou l’autre langage refuse un texte qui tient.
La longueur n’est pas la taille en octets
Aucun des cinq décomptes ci-dessus n’est un nombre d’octets, et il est facile de confondre les deux. Un décompte est une propriété du texte lui-même ; une taille en octets est une propriété du texte une fois écrit dans un encodage donné, si bien qu’une même chaîne occupe une taille en UTF-8 et une autre en UTF-16. Ce qui se mesure en octets se mesure donc après encodage, et l’encodage choisi fait partie de la réponse.
- UTF-8 est ce qu’emploie à peu près tout, et il est de largeur variable : une lettre, un chiffre ou un signe de ponctuation ASCII fait un octet, la plupart des caractères accentués et non latins en font deux ou trois, et beaucoup d’emojis en font quatre. Cent caractères ne font cent octets que si tous sont en ASCII — ces mêmes cent caractères en grec, en hébreu, en arabe ou en chinois en occupent le double ou le triple.
- Python : len() compte des points de code, il faut donc encoder avant de mesurer. len(text.encode('utf-8')) donne le nombre d’octets UTF-8, et nommer un autre codec à cet endroit donne un autre nombre, ce qui est précisément l’enjeu.
- JavaScript : .length compte des unités UTF-16, ce n’est donc pas non plus un nombre d’octets. new TextEncoder().encode(text).length donne le nombre d’octets UTF-8, dans le navigateur comme dans Node, et TextEncoder ne produit jamais autre chose que de l’UTF-8 : il n’y a aucun codec à nommer.
- Vérifiez dans quelle unité votre limite est écrite avant de compter quoi que ce soit. Certains moteurs de base de données déclarent une colonne en caractères et d’autres en octets, la valeur d’un en-tête HTTP et la taille d’un fichier sont en octets, et une règle écrite pour des humains, c’est ce qu’affiche la case « Caractères ». Tout ce qui se mesure en caractères est déjà ci-dessus ; tout ce qui se mesure en octets réclame une longueur après encodage.
Une fois le nombre d’octets obtenu, le Convertisseur de tailles de données est la suite : il convertit un nombre brut d’octets dans les deux systèmes d’unités à la fois — celui bâti sur les puissances de mille et celui bâti sur les puissances de deux — et montre comment les outils de votre machine annoncent chacun la même taille. Cette page s’arrête où l’encodage commence ; l’autre part d’un nombre d’octets.
Questions fréquentes
- Quel décompte correspond à la longueur de chaîne de JavaScript ?
- La valeur des unités UTF-16 correspond à la propriété .length brute de JavaScript. Si votre code découpe ou indexe des chaînes, c’est ce nombre qui régit son comportement.
- Pourquoi un emoji compte-t-il pour plusieurs caractères ?
- De nombreux emojis sont composés de plusieurs points de code Unicode assemblés. En tant que graphème (ce que vous voyez), c’est un caractère, mais ses décomptes de points de code et d’UTF-16 sont plus élevés, c’est pourquoi chaque mesure est affichée séparément.
- Compte-t-il les espaces et sauts de ligne finaux ?
- Oui. Chaque caractère que vous collez est compté, y compris les espaces de début et de fin et les sauts de ligne. Si les totaux semblent plus élevés que prévu, vérifiez la présence d’espaces finaux invisibles.
- Mon texte est-il envoyé à un serveur ?
- Non. Tout le comptage se fait dans votre navigateur. Le texte que vous saisissez ou collez ne quitte jamais votre appareil.
- Qu’est-ce qu’un graphème ?
- Un graphème, ou « groupe de graphèmes », est un caractère tel que l’utilisateur le perçoit — la plus petite unité qu’un lecteur appellerait un seul caractère, même si elle est formée de plusieurs points de code.
- En quoi les octets diffèrent-ils de ces décomptes ?
- Les octets dépendent de l’encodage. En UTF-8, une lettre ASCII fait un octet, la plupart des caractères accentués et non latins deux ou trois, et beaucoup d’emojis quatre. Aucune des cinq mesures ici n’est un décompte d’octets, donc pour les champs limités en octets, encodez d’abord en UTF-8.
Outils connexes
- Convertisseur de tailles de données
Aucun des comptes présentés ici n’est une taille en octets : celle-ci n’existe qu’une fois le texte encodé. Ce nombre une fois obtenu, cette page-là le lit en unités décimales et binaires côte à côte et dit comment chaque système d’exploitation l’appellera.
- Testeur de regex
Testez des expressions régulières — correspondance, remplacement, découpage.
- Comparateur de textes
Comparez deux textes — chaque ligne et chaque mot modifiés.
- Inspecteur de caractères Unicode
Voyez exactement de quels caractères un texte est fait.