Калькулятор длины строки
Вставьте строку, и инструмент сообщит ее длину в четырех разных смыслах, .length в стиле JavaScript (кодовые единицы UTF-16), кодовые точки Unicode, кластеры графем (то, что пользователь воспринимает как один символ) и байты UTF-8 (то, что на самом деле хранит столбец вашей базы данных). Эти числа расходятся для любой строки с эмодзи, флагами или комбинируемыми знаками, и это расхождение является источником множества багов.
Четыре смысла длины строки
-
1
Кодовые единицы UTF-16
То, что возвращает `str.length` в JavaScript. 1 для большинства символов, 2 для любой кодовой точки за пределами U+FFFF (эмодзи, древние письменности).
-
2
Кодовые точки
По одной на каждый скаляр Unicode. Эмодзи: по 1 каждый; последовательности ZWJ: несколько.
-
3
Кластеры графем
То, что пользователь называет «одним символом». `🇺🇸`: это 2 кодовые точки, но 1 графема. `n̈`: это 2 кодовые точки, но 1 графема.
-
4
Байты UTF-8
То, что хранит ваша БД. ASCII = 1 байт каждый; распространенные европейские = 2; CJK = 3; большинство эмодзи = 4.
Примеры
| Строка | JS .length | Кодовые точки | Графемы | Байты UTF-8 |
|---|---|---|---|---|
hello |
5 | 5 | 5 | 5 |
café |
4 | 4 | 4 | 5 |
😀 |
2 | 1 | 1 | 4 |
🇺🇸 |
4 | 2 | 1 | 8 |
👨👩👧 (семья) |
8 | 5 | 1 | 18 |
n̈ (n + диерезис) |
2 | 2 | 1 | 3 |
Почему числа различаются
Строки JavaScript, это UTF-16, поэтому кодовая точка выше U+FFFF хранится как суррогатная пара, две кодовые единицы UTF-16. "😀".length === 2. Пользователи это ненавидят, потому что воспринимают 😀 как один символ.
Графемы идут дальше: флаг страны, это две кодовые точки региональных индикаторов, которые пользователь видит как один флаг. "🇺🇸".length === 4 в JavaScript, что кажется абсурдом, но так оно и есть. Чтобы перебирать графемы, используйте Intl.Segmenter (современный), библиотеку grapheme-splitter или обрабатывайте вручную.
Байты UTF-8: что хранит ваша база данных
Для столбца типа VARCHAR(255):
- В MySQL
utf8(фактически: utf8mb3) 255, это байты.caféзанимает 5 байтов, так что помещается 51 копия. - В MySQL
utf8mb4(настоящий UTF-8, включая эмодзи) это по-прежнему байты, но кодировка поддерживает 4-байтовые последовательности. - В Postgres
VARCHAR(255)255, это символы (кодовые точки), а не байты. - В SQL Server
VARCHARзависит от collation;NVARCHARсчитает 2-байтовые единицы UCS-2.
Если вы задаете размер полей БД по видимому пользователю лимиту символов, используйте байты × 4 для запаса в столбцах UTF-8, каждая графема потенциально занимает до 4 байтов на кодовую точку, а последовательности ZWJ добавляют еще.
Подсчет символов в стиле Twitter
Twitter считает твит по особому правилу: кодовые точки, но эмодзи и идеограммы CJK считаются за 2. Твит на 100% из ASCII может быть 280 символов; твит со 140 эмодзи достигает максимума на 140 «символах».
Подсчет SMS: 160 символов в 7-битном GSM. Любой не-GSM символ (á, é, ñ, эмодзи) переключает кодировку на UCS-2, и длина вашего сообщения падает до 70 символов.
Практическое применение
- Подбор размера столбцов БД, проверьте количество байтов перед написанием миграции.
- Контроль квоты API, большинство API считают байты, а не символы.
- Валидация форм, показывайте пользователю точный подсчет символов, соответствующий его ожиданиям (графемы).
- Отладка производительности, почему этот regex итерирует медленно? Потому что ввод в 3 раза длиннее в кодовых единицах, чем в графемах.
Часто задаваемые вопросы
Этот эмодзи, последовательность ZWJ, объединяющая несколько кодовых точек (например, эмодзи семьи, это 7 кодовых точек). Twitter считает его за 2 символа по правилу веса Unicode; ваш редактор показывает 1 графему. Оба технически правы, просто они измеряют разное.
В базах UTF-8 закладывайте 4 байта на ожидаемый символ для запаса. Поле на 100 символов (графем) должно быть VARCHAR(400) байтов, или, если ваша БД считает в символах, как Postgres, VARCHAR(100) с настройкой charset.
В JavaScript зависит от формы композиции. NFC-композированный (U+00E1) имеет длину 1; NFD-декомпозированный (U+0061 + U+0301) имеет длину 2. Один и тот же видимый символ, разные последовательности байтов.
Эмодзи семей и профессий, это длинные последовательности ZWJ. Шрифты без полной поддержки отрисовывают каждую кодовую точку как отдельный глиф, поэтому 👨💻 превращается в 👨+💻. Обновление шрифта ОС это исправляет.
Сопутствующие инструменты
Генератор названий городов
Создавайте вымышленные названия городов, посёлков, деревень и столиц для миростроения, карт, игр, историй и тестовых данных с короткими заметками к каждому результату.
Переводчик иконок
Введите английский текст, и каждое слово из встроенного списка получит подходящий эмодзи. Скопируйте результат как текст с эмодзи.
Генератор бегущей строки
Создавайте анимированные бегущие заголовки с настраиваемой скоростью, размером шрифта и цветами. Предпросматривайте CSS-строку marquee или панель объявлений вживую в браузере.
Символы стрелок для копирования
Копируйте популярные Unicode-стрелки одним щелчком: прямые, двойные, диагональные, крючковые, круговые и треугольные для документов, чатов и дизайна.
Переводчик Эндермана
Превратите любую фразу в речь Эндермена в стиле Minecraft: растяните гласные и переверните каждое второе слово. Скопируйте результат в чат, на таблички или в посты фанатов.
Символ «меньше или равно»
Копируйте знак ≤ и связанные математические символы сравнения. Включает Unicode, HTML-сущности и разметку LaTeX для электронных таблиц, научных работ и веб-страниц.
Инструмент доступен на других языках
- เครื่องคำนวณความยาวของสตริง [TH]
- Kalkulator długości ciągu znaków [PL]
- Công cụ tính chiều dài chuỗi ký tự [VI]
- Zeichenlängenrechner [DE]
- Kalkulator Panjang String [ID]
- 文字列長計算ツール [JA]
- Calculadora de Longitud de Cadenas [ES]
- 문자열 길이 계산기 [KO]
- Calculadora de Comprimento de String [PT]
- Stränglängdsberäknare [SV]
- Calculateur de longueur de chaîne [FR]
- مقياس طول السلسلة النصية [AR]
- Stringlengteberekenaar [NL]
- 字符串长度计算器 [ZH]
- Dize Uzunluğu Hesaplayıcı [TR]
- String Length Calculator [EN]
- Calcolatore della lunghezza della stringa [IT]