Вопрос: JavaScript эквивалентен printf / string.format


Я ищу хороший эквивалент JavaScript для C / PHP printf()или для программистов на C # / Java, String.Format()( IFormatProviderдля .NET).

Мое основное требование - это формат тысяч разделителей для чисел, но что-то, что обрабатывает множество комбинаций (включая даты), было бы хорошо.

Я понимаю, что Microsoft Ajax библиотека предоставляет версию String.Format(), но нам не нужны все накладные расходы для этой структуры.


1589


источник


Ответы:


Пытаться sprintf () для JavaScript ,


Обновить Хорошо, если вы действительно хотите сделать простой метод формата самостоятельно, не делайте замены последовательно, но делайте их одновременно.

Поскольку большинство других упомянутых предложений не выполняются, когда строка замены предыдущей замены также содержит последовательность форматирования, например:

"{0}{1}".format("{1}", "{0}")

Обычно вы ожидаете, что выход будет {1}{0}но фактический результат {1}{1}, Итак, замените одновременно, как в внушение страха ,


679



Основываясь на ранее предложенных решениях:

// First, checks if it isn't implemented yet.
if (!String.prototype.format) {
  String.prototype.format = function() {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function(match, number) { 
      return typeof args[number] != 'undefined'
        ? args[number]
        : match
      ;
    });
  };
}

"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")

выходы

ASP мертв, но ASP.NET жив! ASP {2}


Если вы предпочитаете не изменять Stringпрототип:

if (!String.format) {
  String.format = function(format) {
    var args = Array.prototype.slice.call(arguments, 1);
    return format.replace(/{(\d+)}/g, function(match, number) { 
      return typeof args[number] != 'undefined'
        ? args[number] 
        : match
      ;
    });
  };
}

Дает вам гораздо более знакомое:

String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');

с тем же результатом:

ASP мертв, но ASP.NET жив! ASP {2}


1267



Это смешно, потому что Stack Overflow фактически имеет собственную функцию форматирования для Stringпрототип называется formatUnicorn, Попробуй! Войдите в консоль и введите что-то вроде:

"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});

Firebug

Вы получаете этот результат:

Hello, Gabriel, are you feeling OK?

Вы можете использовать объекты, массивы и строки в качестве аргументов! Я получил свой код и переработал его для создания новой версии String.prototype.format:

String.prototype.formatUnicorn = String.prototype.formatUnicorn ||
function () {
    "use strict";
    var str = this.toString();
    if (arguments.length) {
        var t = typeof arguments[0];
        var key;
        var args = ("string" === t || "number" === t) ?
            Array.prototype.slice.call(arguments)
            : arguments[0];

        for (key in args) {
            str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
        }
    }

    return str;
};

Обратите внимание на умных Array.prototype.slice.call(arguments)call - это означает, что если вы вставляете аргументы, которые являются строками или цифрами, а не одним объектом в стиле JSON, вы получаете C # String.Formatпочти точно.

"a{0}bcd{1}ef".formatUnicorn("foo", "bar"); // yields "aFOObcdBARef"

Это потому что Array«s sliceзаставит все argumentsв Array, было ли это изначально или нет, и keyбудет индекс (0, 1, 2 ...) каждого элемента массива, принудительно связанного с строкой (например, «0», поэтому "\\{0\\}"для вашего первого шаблона регулярного выражения).

Ухоженная.


352



Форматирование чисел в JavaScript

Я попал на эту страницу вопросов, надеясь найти, как номера формата в JavaScript, не представляя еще одну библиотеку. Вот что я нашел:

Округление чисел с плавающей запятой

Эквивалент sprintf("%.2f", num)в JavaScript, кажется, num.toFixed(2), который форматирует numдо 2 знаков после запятой, с округлением (но см. комментарий @ ars265 о Math.roundниже).

(12.345).toFixed(2); // returns "12.35" (rounding!)
(12.3).toFixed(2); // returns "12.30" (zero padding)

Экспоненциальная форма

Эквивалент sprintf("%.2e", num)является num.toExponential(2),

(33333).toExponential(2); // "3.33e+4"

Шестнадцатеричные и другие базы

Чтобы напечатать числа в базе B, попробуйте num.toString(B), JavaScript поддерживает автоматическое преобразование на и с баз с 2 по 36 (кроме того, некоторые браузеры ограниченная поддержка кодировки base64 ).

(3735928559).toString(16); // to base 16: "deadbeef"
parseInt("deadbeef", 16); // from base 16: 3735928559

Справочные страницы

Краткое руководство по форматированию номера JS

Страница справки Mozilla для toFixed () (со ссылками на toPrecision (), toExponential (), toLocaleString (), ...)


288



jsxt, Zippo

Эта опция подходит лучше.

String.prototype.format = function() {
    var formatted = this;
    for (var i = 0; i < arguments.length; i++) {
        var regexp = new RegExp('\\{'+i+'\\}', 'gi');
        formatted = formatted.replace(regexp, arguments[i]);
    }
    return formatted;
};

С помощью этой опции я могу заменить такие строки:

'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');

С вашим кодом второй {0} не будет заменен. ;)


168



С ES6 вы можете использовать строковые строки :

let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!

Имейте в виду, что строки шаблонов окруженный обратными окнами `вместо (одиночных) кавычек.

Для дополнительной информации:

https://developers.google.com/web/updates/2015/01/ES6-Template-Strings

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings

Заметка: Проверьте сайт mozilla, чтобы найти список поддерживаемых браузеров.


161



Я использую эту простую функцию:

String.prototype.format = function() {
    var formatted = this;
    for( var arg in arguments ) {
        formatted = formatted.replace("{" + arg + "}", arguments[arg]);
    }
    return formatted;
};

Это очень похоже на string.format:

"{0} is dead, but {1} is alive!".format("ASP", "ASP.NET")

90



Here's a minimal implementation of sprintf in JavaScript: it only does "%s" and "%d", but I have left space for it to be extended. It is useless to the OP, but other people who stumble across this thread coming from Google might benefit from it.

function sprintf() {
    var args = arguments,
    string = args[0],
    i = 1;
    return string.replace(/%((%)|s|d)/g, function (m) {
        // m is the matched format, e.g. %s, %d
        var val = null;
        if (m[2]) {
            val = m[2];
        } else {
            val = args[i];
            // A switch statement so that the formatter can be extended. Default is %s
            switch (m) {
                case '%d':
                    val = parseFloat(val);
                    if (isNaN(val)) {
                        val = 0;
                    }
                    break;
            }
            i++;
        }
        return val;
    });
}

Example:

alert(sprintf('Latitude: %s, Longitude: %s, Count: %d', 41.847, -87.661, 'two'));
// Expected output: Latitude: 41.847, Longitude: -87.661, Count: 0

In contrast with similar solutions in previous replies, this one does all substitutions in one go, so it will not replace parts of previously replaced values.


48



For Node.js users there is util.format which has printf-like functionality:

util.format("%s world", "Hello")

45