Какой JavaScript-эквивалент существует для функции printf() из C/PHP или String.Format() из C#/Java?
Я ищу JavaScript-функцию для форматирования строк, похожую на то, как работает printf() в C/PHP или String.Format() в C#/Java. Моя основная потребность - форматирование чисел с разделителями тысяч, но я также хотел бы найти решение, которое может обрабатывать различные параметры форматирования, включая даты.
Я знаю, что библиотека Ajax от Microsoft предоставляет реализацию String.Format(), но я предпочитаю легковесное решение, которое не требует всей библиотеки.
В JavaScript нет встроенных функций printf() или String.Format(), как в C/PHP или C#/Java, но доступно несколько легковесных решений. Наиболее распространенные подходы включают использование встроенного API Intl.NumberFormat для форматирования чисел с разделителями тысяч или создание пользовательских функций форматирования, поддерживающих различные шаблоны.
Содержание
- Встроенные решения JavaScript
- Легковесные библиотеки форматирования строк
- Реализация пользовательской функции форматирования
- Форматирование чисел с разделителями тысяч
- Варианты форматирования даты
- Сравнение решений
Встроенные решения JavaScript
JavaScript предоставляет несколько нативных API, которые могут заменить функциональность printf/String.Format без необходимости использования внешних библиотек.
API Intl.NumberFormat
Объект Intl.NumberFormat — это современное встроенное решение для форматирования чисел с разделителями тысяч и форматирования, зависящего от локали:
const number = 1234567.89;
// Базовое форматирование чисел с разделителями тысяч
const formatted = new Intl.NumberFormat('en-US').format(number);
console.log(formatted); // "1,234,567.89"
// Для разных локалей
const germanFormat = new Intl.NumberFormat('de-DE').format(number);
console.log(germanFormat); // "1.234.567,89"
// С форматированием валюты
const currencyFormat = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(number);
console.log(currencyFormat); // "$1,234,567.89"
Шаблонные литералы с функциями-тегами
Современные шаблонные литералы JavaScript с функциями-тегами предоставляют гибкий способ создания форматированных строк:
// Простой шаблонный литерал
const name = "Мир";
const greeting = `Привет, ${name}!`;
// Более сложное форматирование с пользовательской функцией-тегом
function format(strings, ...values) {
return strings.reduce((result, string, i) => {
return result + string + (values[i] || '');
}, '');
}
const result = format`Цена составляет $${1234.56}, а количество равно ${1000}`;
console.log(result); // "Цена составляет $1234.56, а количество равно 1000"
Легковесные библиотеки форматирования строк
Несколько легковесных библиотек предоставляют функциональность printf/String.Format без излишней тяжеловесности больших фреймворков.
sprintf-js
Популярная легковесная реализация функциональности sprintf:
// Установка: npm install sprintf-js
const sprintf = require('sprintf-js').sprintf;
// Базовое форматирование строк
const formatted = sprintf("Привет %s, у вас %d сообщений", "Алиса", 5);
console.log(formatted); // "Привет Алиса, у вас 5 сообщений"
// Форматирование чисел с разделителями тысяч
const number = 1234567;
const formattedNum = sprintf("%'d", number); // Использование ' в качестве разделителя тысяч
console.log(formattedNum); // "1,234,567"
string-format
Еще один легковесный вариант с простым синтаксисом:
// Установка: npm install string-format
const format = require('string-format');
// Базовое использование
const result = format("Привет {0}, у вас {1} сообщений", "Алиса", 5);
console.log(result); // "Привет Алиса, у вас 5 сообщений"
// Именованные параметры
const namedResult = format("Привет {name}, у вас {count} сообщений", {
name: "Алиса",
count: 5
});
console.log(namedResult); // "Привет Алиса, у вас 5 сообщений"
util.format
Node.js предоставляет встроенный метод util.format, похожий на printf:
const util = require('util');
const formatted = util.format("Привет %s, у вас %d сообщений", "Алиса", 5);
console.log(formatted); // "Привет Алиса, у вас 5 сообщений"
Реализация пользовательской функции форматирования
Вы можете создать собственную легковесную функцию форматирования, охватывающую функциональность, похожую на printf:
function printf(format, ...args) {
return format.replace(/%([%sdf])/g, function(match, type) {
const value = args.shift();
switch(type) {
case '%': return '%';
case 's': return String(value);
case 'd': return Math.floor(value);
case 'f': return parseFloat(value).toFixed(2);
default: return match;
}
});
}
// Примеры использования
const result1 = printf("Привет %s, у вас %d сообщений", "Алиса", 5);
const result2 = printf("Цена составляет $%f", 1234.567);
console.log(result1); // "Привет Алиса, у вас 5 сообщений"
console.log(result2); // "Цена составляет $1234.57"
Для более комплексного форматирования, вот расширенная версия:
function formatString(format, ...args) {
return format.replace(/%(%)|(%(\d+)\$)?([-+ 0#])*(\d+)?(?:\.(\d+))?([diufFeEgGcsb])|{(\d+)(?::([^}]+))?}/g, function(match, literal, positional, pos, flags, width, precision, type, index, formatSpec) {
let value;
// Обработка позиционных аргументов в стиле printf
if (positional) {
value = args[parseInt(pos) - 1];
}
// Обработка стиля шаблонных литералов {индекс}
else if (index !== undefined) {
value = args[parseInt(index)];
}
// Обработка последовательных аргументов в стиле printf
else if (!literal) {
value = args.shift();
}
if (value === undefined) return match;
// Форматирование в зависимости от типа
switch(type) {
case '%': return '%';
case 's': return String(value);
case 'd': case 'i': return Math.floor(value).toLocaleString();
case 'f': case 'F': return parseFloat(value).toFixed(precision || 2).toLocaleString();
case 'e': case 'E': return parseFloat(value).toExponential(precision || 2);
case 'g': case 'G': return parseFloat(value).toPrecision(precision || 6);
case 'c': return value;
case 'b': return parseInt(value).toString(2);
default: return String(value);
}
});
}
// Примеры использования
console.log(formatString("Привет %s, баланс: $%d", "Алиса", 1234567));
console.log(formatString("Точность: %0.2f", 3.14159));
console.log(formatString("Научное: %e", 1000000));
console.log(formatString("Шаблон: {0} имеет {1:,d} очков", "Боб", 9876543));
Форматирование чисел с разделителями тысяч
Для вашей основной необходимости форматирования чисел с разделителями тысяч, вот несколько подходов:
Использование Intl.NumberFormat (рекомендуется)
function formatNumber(number, locale = 'en-US') {
return new Intl.NumberFormat(locale).format(number);
}
// Использование
console.log(formatNumber(1234567)); // "1,234,567"
console.log(formatNumber(1234567.89, 'de-DE')); // "1.234.567,89"
console.log(formatNumber(1234567, 'fr-FR')); // "1 234 567"
Использование пользовательского форматирования чисел
function formatNumberWithSeparators(number, separator = ',') {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
}
// Использование
console.log(formatNumberWithSeparators(1234567)); // "1,234,567"
console.log(formatNumberWithSeparators(1234567, '.')); // "1.234.567"
Комбинирование с другим форматированием чисел
function formatCurrency(amount, currency = 'USD', locale = 'en-US') {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency,
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount);
}
function formatPercent(value, decimals = 2, locale = 'en-US') {
return new Intl.NumberFormat(locale, {
style: 'percent',
minimumFractionDigits: decimals,
maximumFractionDigits: decimals
}).format(value / 100);
}
// Использование
console.log(formatCurrency(1234567.89)); // "$1,234,567.89"
console.log(formatPercent(0.1567)); // "15.67%"
Варианты форматирования даты
JavaScript также предоставляет надежное форматирование даты через API Intl.DateTimeFormat:
function formatDate(date, locale = 'en-US', options = {}) {
const defaultOptions = {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
};
return new Intl.DateTimeFormat(locale, { ...defaultOptions, ...options }).format(date);
}
// Примеры использования
const now = new Date();
console.log(formatDate(now));
// "31 декабря 2024 г., 23:59:59"
console.log(formatDate(now, 'de-DE', {
year: 'numeric',
month: 'short',
day: 'numeric'
}));
// "31. Dez. 2024"
console.log(formatDate(now, 'ja-JP', {
era: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
}));
// "2024年12月31日 火曜日"
Для форматирования даты в стиле printf, вы можете расширить пользовательскую функцию форматирования:
function formatDateTime(format, date = new Date(), ...args) {
const pad = (num, width = 2) => num.toString().padStart(width, '0');
const dateObj = new Date(date);
// Спецификаторы формата даты
const formatMap = {
'%Y': dateObj.getFullYear(),
'%y': dateObj.getFullYear() % 100,
'%m': pad(dateObj.getMonth() + 1),
'%d': pad(dateObj.getDate()),
'%H': pad(dateObj.getHours()),
'%M': pad(dateObj.getMinutes()),
'%S': pad(dateObj.getSeconds()),
'%A': dateObj.toLocaleDateString('ru-RU', { weekday: 'long' }),
'%B': dateObj.toLocaleDateString('ru-RU', { month: 'long' }),
'%b': dateObj.toLocaleDateString('ru-RU', { month: 'short' }),
};
// Замена спецификаторов формата
let result = format;
for (const [spec, value] of Object.entries(formatMap)) {
result = result.replace(new RegExp(spec.replace('%', '\\%'), 'g'), value);
}
// Обработка оставшегося форматирования в стиле printf
return result.replace(/%(%)|(%(\d+)\$)?([-+ 0#])*(\d+)?(?:\.(\d+))?([diufFeEgGcsb])/g, function(match, literal, positional, pos, flags, width, precision, type) {
if (literal) return '%';
return args.shift() || '';
});
}
// Использование
console.log(formatDateTime("Сегодня %A, %B %d, %Y"));
console.log(formatDateTime("Время: %H:%M:%S", new Date(), "дополнительные", "аргументы"));
Сравнение решений
| Решение | Плюсы | Минусы | Лучше всего подходит для |
|---|---|---|---|
Intl.NumberFormat |
Встроенный, зависящий от локали, без зависимостей | Ограничен форматированием чисел | Современные приложения, требующие международного форматирования чисел |
sprintf-js |
Полная совместимость с printf, легковесный | Требует внешней зависимости | Разработчикам C/PHP, знакомым с синтаксисом |
| Пользовательская функция форматирования | Полный контроль, без зависимостей | Требует поддержки | Проектов с конкретными, специализированными потребностями форматирования |
| Шаблонные литералы | Нативный JavaScript, читаемый | Ограниченные возможности форматирования | Простых задач интерполяции строк |
util.format |
Встроенный (Node.js), знакомый синтаксис | Только для Node.js | Серверных приложений на JavaScript |
Для ваших конкретных потребностей я рекомендую начать с Intl.NumberFormat для форматирования чисел с разделителями тысяч, так как он встроенный, зависит от локали и не требует внешних зависимостей. Для более комплексного форматирования строк, библиотеки вроде sprintf-js предоставляют отличную совместимость со стилем printf, оставаясь легковесными.
Заключение
JavaScript предоставляет несколько отличных альтернатив printf() из C/PHP и String.Format() из C#/Java, варьирующихся от встроенных API до легковесных библиотек. Для вашей основной необходимости форматирования чисел с разделителями тысяч, API Intl.NumberFormat является рекомендуемым современным решением. Для более комплексного форматирования строк, библиотеки вроде sprintf-js предлагают функциональность в стиле printf без необходимости использования больших фреймворков. Подход с пользовательской реализацией дает полный контроль над поведением форматирования при минимальном размере.
Основные рекомендации:
- Используйте
Intl.NumberFormatдля форматирования чисел с разделителями тысяч и поддержки локалей - Рассмотрите
sprintf-jsдля комплексного форматирования строк в стиле printf - Реализуйте пользовательские функции форматирования для специфических потребностей проекта
- Используйте шаблонные литералы для простых задач интерполяции строк
- Комбинируйте
Intl.NumberFormatсIntl.DateTimeFormatдля последовательного международного форматирования
Эти решения предоставляют необходимую функциональность, сохраняя легковесный подход, который вы предпочитаете, и устраняя необходимость в больших фреймворках, таких как библиотека Ajax от Microsoft.