qatoolqa.ru

Счётчик символов, слов и байтов

Сколько в тексте символов, слов, байтов и графем — четыре числа сразу. Нужно, когда поле ограничено на бэкенде байтами, в интерфейсе — видимыми знаками, а пользователь вставляет эмодзи. Здесь видно, где именно превышен лимит и почему счётчик в форме показывает другое.

Текст

Сгенерировать строку

Числа только подставляют длину, строку выдаёт «Сгенерировать»; 255 и 256 рядом не случайно — это граница varchar(255). Готовая строка попадает в поле «Текст» и сразу пересчитывается.

Сколько получилось

Почему числа расходятся

Пока текст — латиница без эмодзи, все четыре меры совпадают, и разницы будто нет. Она появляется ровно там, где начинаются ошибки.

Символы (UTF-16) — то, что вернёт .length в JavaScript и по чему считает maxlength у поля ввода. Меряет не символы, а 16-битные единицы: эмодзи и редкие иероглифы занимают две.

Кодовые точки — собственно символы Unicode. Для эмодзи уже вдвое меньше, чем предыдущая строка.

Графемы — то, что человек видит как один знак. Семья 👨‍👩‍👧‍👦 — одна графема, но семь кодовых точек и одиннадцать единиц UTF-16. Флаги и буквы с ударением — та же история.

Байты UTF-8 — сколько текст займёт в базе и в теле запроса. Латиница по байту на символ, кириллица по два, эмодзи по четыре. Поэтому «привет» — шесть символов, но двенадцать байт.

Чем это грозит. Поле с maxlength=255 пропустит 255 кириллических символов, а колонка, где лимит в байтах, отрежет их на 127-м. Обрезка текста «по символам» через .slice() умеет разрубить эмодзи пополам, и вместо него приезжает знак вопроса в ромбике.

Пробелы меняют не длину, а поведение. Символов, кодовых точек и графем от них не прибавляется — пробел такой же символ, — но сплошная строка не переносится по словам и разносит вёрстку. Проверять стоит оба случая: что аномальный текст не ломает раскладку и что обычный переносится нормально. На кириллице пробелы вдобавок облегчают строку в байтах: пробел весит один байт, буква два.

Частые вопросы

Почему три числа, а не одно?

Символы, байты и графемы — разные величины. Эмодзи с модификатором — одна графема, но несколько символов и до десятка байт. Поле с ограничением в базе считает байты, а пользователь — видимые знаки.

Как это связано с varchar(255)?

В базах с байтовым лимитом русский текст в UTF-8 занимает по два байта на букву, то есть в поле влезет вдвое меньше символов, чем кажется. Здесь видно оба числа сразу.

Пробелы учитываются?

Показаны оба варианта — с пробелами и без, плюс отдельно строки и слова.