Mb strwidth: примеры (PHP)
mb_strwidth(string $string, ?string $encoding = null): intФункция mb_strwidth в PHP
Функция mb_strwidth вычисляет ширину строки в символах, учитывая особенности многобайтовых кодировок и ширину символов в моноширинных шрифтах. Она полезна при форматировании текста для терминалов или в случаях, где требуется выравнивание с учетом полной и половинной ширины символов.
Функция применяется при работе с текстами на азиатских языках (китайский, японский, корейский), где часть символов имеет полную ширину, а часть - половинную. Также используется для точного подсчета места, которое займет строка в моноширинном отображении.
int mb_strwidth(string $string, string|null $encoding = null)
$string - анализируемая строка. Обязательный параметр.
$encoding - кодировка входной строки. Если не указана, используется внутренняя кодировка. Необязательный параметр.
Примеры использования mb_strwidth
echo mb_strwidth("Hello"); // 5
echo mb_strwidth("Привет"); // 6 (кириллица имеет полную ширину)
echo mb_strwidth("こんにちは"); // 10 (хирагана - полная ширина)
echo mb_strwidth("abc123"); // 65 6 10 6
$str = "Пример";
echo mb_strwidth($str, 'UTF-8'); // 66
$text = "Hello 世界!"; // Латиница + иероглифы
$width = mb_strwidth($text);
echo "Ширина строки: $width";Ширина строки: 13
Похожие функции в PHP
Подсчитывает количество символов в строке. Отличие от mb_strwidth в том, что каждый символ считается как 1, независимо от его визуальной ширины.
echo mb_strlen("Hello"); // 5
echo mb_strwidth("Hello"); // 5 (одинаково для латиницы)
echo mb_strlen("世界"); // 2
echo mb_strwidth("世界"); // 4 (иероглифы имеют полную ширину)Подсчитывает количество байт в строке. Не учитывает многобайтовые кодировки, поэтому для UTF-8 может давать неверные результаты для подсчета символов.
Аналог mb_strlen из расширения iconv. Работает с различными кодировками, но не учитывает ширину символов.
mb_strwidth предпочтительнее при работе с восточными языками и в задачах визуального форматирования. mb_strlen лучше подходит для подсчета реального количества символов.
Типичные ошибки
// Если передать строку в неверной кодировке
$str = mb_convert_encoding("Пример", 'Windows-1251', 'UTF-8');
echo mb_strwidth($str, 'UTF-8'); // Может вернуть неожиданный результат6 (но может варьироваться в зависимости от окружения)
// Управляющие символы и эмодзи
$str = "Line1\nLine2"; // Символ новой строки
$str2 = "Hello ????"; // Эмодзи
echo mb_strwidth($str); // 10
echo mb_strwidth($str2); // 7 (эмодзи считается как 2 символа ширины)10 7
Ожидание, что результат mb_strwidth всегда будет равен количеству символов для европейских языков. Для символов с комбинирующими диакритическими знаками это не так.
Изменения в версиях PHP
Параметр encoding стал опциональным и по умолчанию равен null. В предыдущих версиях рекомендовалось явно указывать кодировку.
Добавлена поддержка символов эмодзи. Ранее эмодзи могли неправильно учитываться при подсчете ширины.
В PHP 4 и ранних версиях PHP 5 функция была доступна только при включенном расширении mbstring. Сейчас расширение обычно включено по умолчанию.
Расширенные примеры
function formatTableRow($name, $value) {
$width = 30;
$nameWidth = mb_strwidth($name);
$dots = str_repeat('.', $width - $nameWidth);
return $name . $dots . ' ' . $value;
}
echo formatTableRow('Продукт', '150 руб.') . "\n";
echo formatTableRow('Доставка', '300 руб.') . "\n";
echo formatTableRow('Сумма', '450 руб.');Продукт........................ 150 руб. Доставка...................... 300 руб. Сумма......................... 450 руб.
function truncateByWidth($string, $maxWidth, $suffix = '...') {
if (mb_strwidth($string) <= $maxWidth) {
return $string;
}
$result = '';
$currentWidth = 0;
$suffixWidth = mb_strwidth($suffix);
for ($i = 0; $i < mb_strlen($string); $i++) {
$char = mb_substr($string, $i, 1);
$charWidth = mb_strwidth($char);
if ($currentWidth + $charWidth + $suffixWidth > $maxWidth) {
break;
}
$result .= $char;
$currentWidth += $charWidth;
}
return $result . $suffix;
}
echo truncateByWidth('Очень длинная строка с разными символами: 你好', 20);Очень длинная строка...
function visualWidth($string) {
// Удаляем ANSI escape-последовательности
$cleaned = preg_replace('/\x1b\[[0-9;]*m/', '', $string);
return mb_strwidth($cleaned);
}
$colored = "\033[31mКрасный текст\033[0m";
echo visualWidth($colored);12
Аналоги в других языках
Модуль wcwidth предоставляет функцию wcswidth, которая работает аналогично.
import wcwidth
print(wcwidth.wcswidth('Hello 世界!'))13
Mb strwidth в Javascript
Нативный аналог отсутствует. Можно использовать библиотеку string-width из npm.
const stringWidth = require('string-width');
console.log(stringWidth('Hello 世界!'));13
Mb strwidth в MySQL
Функция CHAR_LENGTH подсчитывает символы, но не учитывает их ширину. Специальной функции для определения ширины нет.
SELECT CHAR_LENGTH('Hello 世界!');8
В отличие от PHP, Python требует установки дополнительного модуля. JavaScript не имеет встроенного решения. MySQL вообще не предоставляет такой функциональности.