Pregunta JavaScript equivalente a printf / String.Format


Estoy buscando un buen JavaScript equivalente al C / PHP printf() o para C # / programadores de Java, String.Format() (IFormatProvider para .NET).

Mi requisito básico es un formato de separador de miles de números por ahora, pero algo que maneje muchas combinaciones (incluyendo fechas) sería bueno.

Me doy cuenta de que Microsoft Ajax la biblioteca proporciona una versión de String.Format(), pero no queremos toda la sobrecarga de ese marco.


1605
2018-01-12 20:02


origen


Respuestas:


Tratar sprintf () para JavaScript.


ActualizarDe acuerdo, si realmente quieres hacer un método de formateo simple por tu cuenta, no hagas los reemplazos sucesivamente sino que los hagas simultáneamente.

Porque la mayoría de las otras propuestas que se mencionan fallan cuando una cadena de reemplazo anterior también contiene una secuencia de formato como esta:

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

Normalmente, se espera que la salida sea {1}{0} pero el resultado real es {1}{1}. Entonces haga un reemplazo simultaneo, como en sugerencia de fearphage.


684



Sobre la base de las soluciones sugeridas anteriormente:

// 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")

salidas

ASP está muerto, pero ASP.NET está vivo. ASP {2}


Si prefiere no modificar Stringprototipo de s:

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
      ;
    });
  };
}

Te da el mucho más familiar:

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

con el mismo resultado:

ASP está muerto, pero ASP.NET está vivo. ASP {2}


1278



Es divertido porque Stack Overflow en realidad tiene su propia función de formateo para el String prototipo llamado formatUnicorn. ¡Intentalo! Ve a la consola y escribe algo como:

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

Firebug

Obtienes esta salida:

Hello, Gabriel, are you feeling OK?

¡Puede usar objetos, matrices y cadenas como argumentos! Obtuve su código y lo reelaboré para producir una nueva versión de 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;
};

Tenga en cuenta el inteligente Array.prototype.slice.call(arguments) llamada: eso significa que si ingresas argumentos que son cadenas o números, ni un solo objeto estilo JSON, obtienes C # 's String.Format comportamiento casi exactamente.

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

Eso es porque Arrayes slice forzará lo que sea que esté arguments en una Array, ya sea originalmente o no, y el key será el índice (0, 1, 2 ...) de cada elemento de la matriz coercionado en una cadena (por ejemplo, "0", por lo "\\{0\\}" para su primer patrón de expresiones regulares).

Ordenado.


366



Formato numérico en JavaScript

Llegué a esta página de preguntas con la esperanza de encontrar cómo números de formato en JavaScript, sin introducir otra biblioteca. Esto es lo que he encontrado:

Redondeando números de punto flotante

El equivalente de sprintf("%.2f", num) en JavaScript parece ser num.toFixed(2), que formatos num a 2 decimales, con redondeo (pero vea el comentario de @ ars265 sobre Math.round abajo).

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

Forma exponencial

El equivalente de sprintf("%.2e", num) es num.toExponential(2).

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

Hexadecimal y otras bases

Para imprimir números en la base B, prueba num.toString(B). JavaScript admite la conversión automática desde y hacia las bases 2 a la 36 (además, algunos navegadores tienen soporte limitado para codificación base64)

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

Páginas de referencia

Tutorial rápido sobre el formato de números JS

Página de referencia de Mozilla para to Fixed () (con enlaces a toPrecision (), toExponential (), toLocaleString (), ...)


288



jsxt, Zippo

Esta opción se ajusta mejor.

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;
};

Con esta opción puedo reemplazar cadenas como estas:

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

Con su código, el segundo {0} no sería reemplazado. ;)


168



A partir de ES6, podrías usar cadenas de plantillas:

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

Tenga en cuenta que las cadenas de plantillas son rodeado de palos de atrás `en lugar de (solo) comillas.

Para mayor información:

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

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

Nota: Consulte el sitio de mozilla para encontrar una lista de navegadores compatibles.


168



Yo uso esta simple función:

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

Eso es muy similar a string.format:

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

90



Aquí está un mínimo implementación de sprintf en JavaScript: solo hace "% s" y "% d", pero he dejado espacio para que se extienda. Es inútil para el OP, pero otras personas que tropiecen con este hilo proveniente de Google podrían beneficiarse de ello.

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;
    });
}

Ejemplo:

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

En contraste con soluciones similares en respuestas anteriores, esta hace todas las sustituciones en una ida, por lo que no reemplazará partes de valores reemplazados anteriormente.


48



por Node.js usuarios hay util.format que tiene funcionalidad tipo printf:

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

45