2415 Stimmen

JavaScript-Äquivalent zu printf/String.Format

Ich bin auf der Suche nach einem guten JavaScript-Äquivalent der C/PHP printf() oder für C#/Java-Programmierer, String.Format() ( IFormatProvider für .NET).

Meine Grundanforderung ist ein Tausendertrennzeichenformat für Zahlen für jetzt, aber etwas, das viele Kombinationen (einschließlich Daten) verarbeitet, wäre gut.

Ich weiß, dass Microsofts Ajax Bibliothek bietet eine Version von String.Format() aber wir wollen nicht den gesamten Overhead dieses Rahmens haben.

34voto

3 verschiedene Möglichkeiten zur Formatierung von Javascript-Strings

Es gibt 3 verschiedene Möglichkeiten, eine Zeichenkette zu formatieren, indem Platzhalter durch den Variablenwert ersetzt werden.

  1. Verwendung von Schablonenliteralen (Backticks ``)

    let name = 'John';
    let age = 30;
    // using backticks
    console.log(`${name} is ${age} years old.`);
    // John is 30 years old.
  2. Verkettung verwenden

    let name = 'John'; let age = 30; // using concatenation console.log(name + ' is ' + age + ' years old.'); // John is 30 years old.

  3. Eigene Formatfunktion erstellen

    String.prototype.format = function () { var args = arguments; return this.replace(/{([0-9]+)}/g, function (match, index) { // check if the argument is there return typeof args[index] == 'undefined' ? match : args[index]; }); };

    console.log('{0} is {1} years old.'.format('John', 30));

32voto

jsxt Punkte 1067

JavaScript-Programmierer können String.prototype.sprintf verwenden unter https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js . Nachstehend ein Beispiel:

var d = new Date();
var dateStr = '%02d:%02d:%02d'.sprintf(
    d.getHours(), 
    d.getMinutes(), 
    d.getSeconds());

28voto

Braden Best Punkte 8182

Hinzufügen zu zippoxer Ich verwende diese Funktion:

String.prototype.format = function () {
    var a = this, b;
    for (b in arguments) {
        a = a.replace(/%[a-z]/, arguments[b]);
    }
    return a; // Make chainable
};

var s = 'Hello %s The magic number is %d.';
s.format('world!', 12); // Hello World! The magic number is 12.

Ich habe auch eine Nicht-Prototyp-Version, die ich häufiger wegen ihrer Java-ähnlichen Syntax verwende:

function format() {
    var a, b, c;
    a = arguments[0];
    b = [];
    for(c = 1; c < arguments.length; c++){
        b.push(arguments[c]);
    }
    for (c in b) {
        a = a.replace(/%[a-z]/, b[c]);
    }
    return a;
}
format('%d ducks, 55 %s', 12, 'cats'); // 12 ducks, 55 cats

ES 2015 aktualisiert

All die coolen neuen Funktionen in ES 2015 machen dies viel einfacher:

function format(fmt, ...args){
    return fmt
        .split("%%")
        .reduce((aggregate, chunk, i) =>
            aggregate + chunk + (args[i] || ""), "");
}

format("Hello %%! I ate %% apples today.", "World", 44);
// "Hello World, I ate 44 apples today."

Ich dachte mir, dass, da dies, wie die älteren, nicht tatsächlich analysieren die Buchstaben, könnte es ebenso gut nur ein einzelnes Token verwenden %% . Dies hat den Vorteil, dass es offensichtlich ist und es nicht schwierig ist, eine einzige % . Wenn Sie jedoch benötigen %% aus irgendeinem Grund, müssten Sie es durch sich selbst ersetzen:

format("I love percentage signs! %%", "%%");
// "I love percentage signs! %%"

28voto

Rtlprmft Punkte 19

Ich möchte meine Lösung für das "Problem" mitteilen. Ich habe das Rad nicht neu erfunden, sondern versuche, eine Lösung zu finden, die auf dem basiert, was JavaScript bereits tut. Der Vorteil ist, dass man alle impliziten Konvertierungen umsonst bekommt. Das Setzen der Prototypeigenschaft $ von String ergibt eine sehr schöne und kompakte Syntax (siehe Beispiele unten). Es ist vielleicht nicht die effizienteste Methode, aber in den meisten Fällen, in denen es um die Ausgabe geht, muss sie nicht superoptimiert sein.

String.form = function(str, arr) {
    var i = -1;
    function callback(exp, p0, p1, p2, p3, p4) {
        if (exp=='%%') return '%';
        if (arr[++i]===undefined) return undefined;
        exp  = p2 ? parseInt(p2.substr(1)) : undefined;
        var base = p3 ? parseInt(p3.substr(1)) : undefined;
        var val;
        switch (p4) {
            case 's': val = arr[i]; break;
            case 'c': val = arr[i][0]; break;
            case 'f': val = parseFloat(arr[i]).toFixed(exp); break;
            case 'p': val = parseFloat(arr[i]).toPrecision(exp); break;
            case 'e': val = parseFloat(arr[i]).toExponential(exp); break;
            case 'x': val = parseInt(arr[i]).toString(base?base:16); break;
            case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;
        }
        val = typeof(val)=='object' ? JSON.stringify(val) : val.toString(base);
        var sz = parseInt(p1); /* padding size */
        var ch = p1 && p1[0]=='0' ? '0' : ' '; /* isnull? */
        while (val.length<sz) val = p0 !== undefined ? val+ch : ch+val; /* isminus? */
       return val;
    }
    var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;
    return str.replace(regex, callback);
}

String.prototype.$ = function() {
    return String.form(this, Array.prototype.slice.call(arguments));
}

Hier sind einige Beispiele:

String.format("%s %s", [ "This is a string", 11 ])
console.log("%s %s".$("This is a string", 11))
var arr = [ "12.3", 13.6 ]; console.log("Array: %s".$(arr));
var obj = { test:"test", id:12 }; console.log("Object: %s".$(obj));
console.log("%c", "Test");
console.log("%5d".$(12)); // '   12'
console.log("%05d".$(12)); // '00012'
console.log("%-5d".$(12)); // '12   '
console.log("%5.2d".$(123)); // '  120'
console.log("%5.2f".$(1.1)); // ' 1.10'
console.log("%10.2e".$(1.1)); // '   1.10e+0'
console.log("%5.3p".$(1.12345)); // ' 1.12'
console.log("%5x".$(45054)); // ' affe'
console.log("%20#2x".$("45054")); // '    1010111111111110'
console.log("%6#2d".$("111")); // '     7'
console.log("%6#16d".$("affe")); // ' 45054'

20voto

user437231 Punkte 163

+1 Zippo mit der Ausnahme, dass der Funktionskörper wie unten angegeben sein muss, da sonst bei jeder Iteration die aktuelle Zeichenfolge angehängt wird:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X