Ich suche ein gutes JavaScript-Äquivalent zu C / PHP printf()
oder für C # / Java-Programmierer String.Format()
( IFormatProvider
für .NET).
Meine Grundvoraussetzung ist vorerst ein Tausendertrennzeichenformat für Zahlen, aber etwas, das viele Kombinationen (einschließlich Datumsangaben) verarbeitet, wäre gut.
Ich weiß, dass die Ajax- Bibliothek von Microsoft eine Version von bietet String.Format()
, aber wir wollen nicht den gesamten Overhead dieses Frameworks.
javascript
printf
string.format
Chris S.
quelle
quelle
Antworten:
Ab ES6 können Sie Vorlagenzeichenfolgen verwenden:
Siehe Kims Antwort unten für Details.
Andernfalls:
Versuchen Sie sprintf () für JavaScript .
Wenn Sie wirklich eine einfache Formatierungsmethode selbst ausführen möchten, führen Sie die Ersetzungen nicht nacheinander durch, sondern gleichzeitig.
Da die meisten anderen genannten Vorschläge fehlschlagen, wenn eine Ersetzungszeichenfolge der vorherigen Ersetzung ebenfalls eine Formatsequenz wie die folgende enthält:
Normalerweise würden Sie erwarten, dass die Ausgabe ist,
{1}{0}
aber die tatsächliche Ausgabe ist{1}{1}
. Führen Sie stattdessen einen gleichzeitigen Ersatz durch, wie im Vorschlag von Fearphage .quelle
num.toFixed()
Methode möglicherweise ausreichend!sprintf() for JavaScript
nicht verfügbar.underscore.string
hat neben sprintf, das auf dersprintf() for JavaScript
Implementierung basiert, weitere Funktionen . Davon abgesehen ist die Bibliothek ein ganz anderes Projekt.Aufbauend auf den zuvor vorgeschlagenen Lösungen:
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
Ausgänge
Wenn Sie den
String
Prototyp nicht ändern möchten :Gibt Ihnen das viel vertrautere:
String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');
mit dem gleichen Ergebnis:
quelle
+
Operator), stellen Sie sicher, dass die vollständige("asd {0}"+"fas {1}").format("first", "second");
Zeichenfolge in Klammern steht: Andernfalls wird die Funktion nur auf die zuletzt angehängte Zeichenfolge angewendet.'foo {0}'.format(fnWithNoReturnValue())
. Es würde derzeit zurückkehrenfoo {0}
. Mit Ihren Änderungen würde es zurückkehrenfoo undefined
.Es ist lustig, weil Stack Overflow tatsächlich eine eigene Formatierungsfunktion für den
String
genannten Prototyp hatformatUnicorn
. Versuch es! Gehen Sie in die Konsole und geben Sie Folgendes ein:Sie erhalten diese Ausgabe:
Hello, Gabriel, are you feeling OK?
Sie können Objekte, Arrays und Strings als Argumente verwenden! Ich habe den Code erhalten und ihn überarbeitet, um eine neue Version von zu erstellen
String.prototype.format
:Beachten Sie den cleveren
Array.prototype.slice.call(arguments)
Aufruf - das heißt, wenn Sie Argumente einfügen, die Zeichenfolgen oder Zahlen sind, nicht ein einzelnes Objekt im JSON-Stil, erhalten Sie dasString.Format
Verhalten von C # fast genau.Das liegt daran, dass
Array
'sslice
allesarguments
in ein erzwingtArray
, ob es ursprünglich war oder nicht, und daskey
ist der Index (0, 1, 2 ...) jedes Array-Elements, das zu einer Zeichenfolge gezwungen wird (z. B. "0", also)"\\{0\\}"
für Ihr erstes reguläres Ausdrucksmuster).Ordentlich.
quelle
g
), das denselben Schlüssel mehrmals ersetzen kann. Im obigen Beispiel können Sie{name}
mehrere Sätze im selben Satz verwenden und alle ersetzen lassen.name
ist"blah {adjective} blah"
?Zahlenformatierung in JavaScript
Ich bin auf diese Fragenseite gekommen, um herauszufinden, wie man Zahlen in JavaScript formatiert , ohne eine weitere Bibliothek einzuführen. Folgendes habe ich gefunden:
Rundung von Gleitkommazahlen
Das Äquivalent von
sprintf("%.2f", num)
in JavaScript scheint zu seinnum.toFixed(2)
, dasnum
mit Rundung auf 2 Dezimalstellen formatiert wird (siehe jedoch den Kommentar von @ ars265 weiterMath.round
unten).Exponentialform
Das Äquivalent von
sprintf("%.2e", num)
istnum.toExponential(2)
.Hexadezimal und andere Basen
Versuchen Sie, Zahlen in Basis B zu drucken
num.toString(B)
. JavaScript unterstützt die automatische Konvertierung von und zu den Basen 2 bis 36 (außerdem unterstützen einige Browser die Base64-Codierung nur eingeschränkt ).Referenzseiten
Kurzanleitung zur Formatierung von JS-Nummern
Mozilla-Referenzseite für toFixed () (mit Links zu toPrecision (), toExponential (), toLocaleString (), ...)
quelle
..
funktioniert auch:33333..toExponential(2);
Ab ES6 können Sie Vorlagenzeichenfolgen verwenden :
Beachten Sie, dass Vorlagenzeichenfolgen von Backticks anstelle von (einfachen) Anführungszeichen umgeben sind.
Für weitere Informationen:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Hinweis: Überprüfen Sie die Mozilla-Site, um eine Liste der unterstützten Browser zu finden.
quelle
const compile = (x, y) => `I can call this template string whenever I want.. x=${x}, y=${y}`
...compile(30, 20)
jsxt, Zippo
Diese Option passt besser.
Mit dieser Option kann ich Zeichenfolgen wie diese ersetzen:
Mit Ihrem Code würde die zweite {0} nicht ersetzt. ;)
quelle
Ich benutze diese einfache Funktion:
Das ist string.format sehr ähnlich:
quelle
+=
? sollte esformatted = this.replace("{" + arg + "}", arguments[arg]);
for...in
funktioniert nicht in jedem Browser, wie dieser Code es erwartet. Es werden alle aufzählbaren Eigenschaften durchlaufen, die in einigen Browsern enthalten sindarguments.length
, und in anderen werden die Argumente selbst überhaupt nicht enthalten sein. In jedem Fall, wennObject.prototype
hinzugefügt wird, werden wahrscheinlich alle Ergänzungen in der Gruppe enthalten sein. Der Code sollte eine Standardschleife verwendenfor
und nichtfor...in
."{0} is dead, but {1} is alive!".format("{1}", "ASP.NET") === "ASP.NET is dead, but ASP.NET is alive!"
arg
ist global. Sie müssen dies stattdessen tun:for (var arg in arguments) {
Für Node.js- Benutzer gibt es
util.format
eine printf-ähnliche Funktionalität:quelle
%-20s %5.2f
)Ich bin überrascht, dass niemand etwas verwendet
reduce
hat. Dies ist eine native, präzise und leistungsstarke JavaScript-Funktion.ES6 (EcmaScript2015)
<ES6
Wie es funktioniert:
quelle
printf
Funktion zu erstellen : jsfiddle.net/11szrbx9(...a) => {return a.reduce((p: string, c: any) => p.replace(/%s/, c));
String.prototype.format
in ES6:((a,b,c)=>`${a}, ${b} and ${c}`)(...['me', 'myself', 'I'])
(Beachten Sie, dass dies etwas redundant ist, um besser in Ihr Beispiel zu passen)printf
Typspezifizierer implementieren und Logik zum Auffüllen von Präfixen einschließen. Das vernünftige Durchlaufen des Formatstrings scheint hier die kleine Herausforderung zu sein, imho. Eine gute Lösung, wenn Sie nur Zeichenfolgen ersetzen müssen.Hier ist eine minimale Implementierung von sprintf in JavaScript: Es werden nur "% s" und "% d" ausgeführt, aber ich habe Platz für die Erweiterung gelassen. Es ist für das OP nutzlos, aber andere Leute, die über diesen Thread von Google stolpern, könnten davon profitieren.
Beispiel:
Im Gegensatz zu ähnlichen Lösungen in früheren Antworten werden bei dieser Lösung alle Ersetzungen auf einmal ausgeführt , sodass Teile zuvor ersetzter Werte nicht ersetzt werden.
quelle
JavaScript-Programmierer können String.prototype.sprintf unter https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js verwenden . Unten ist ein Beispiel:
quelle
Neben der
zippoxer
Antwort verwende ich diese Funktion:Ich habe auch eine Nicht-Prototyp-Version, die ich häufiger für ihre Java-ähnliche Syntax verwende:
ES 2015 Update
All die coolen neuen Sachen in ES 2015 machen das viel einfacher:
Ich dachte mir, da dies, wie die älteren, die Buchstaben nicht wirklich analysiert, könnte es genauso gut nur ein einziges Token verwenden
%%
. Dies hat den Vorteil, dass es offensichtlich ist und es nicht schwierig macht, eine einzige zu verwenden%
. Wenn Sie jedoch%%
aus irgendeinem Grund benötigen , müssen Sie es durch sich selbst ersetzen:quelle
+1 Zippo mit der Ausnahme, dass der Funktionskörper wie folgt sein muss oder auf andere Weise die aktuelle Zeichenfolge bei jeder Iteration anhängt:
quelle
'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');
das Ergebnis wirdThe ASP is dead. Don't code {0}. Code PHP that is open source!
. Eine weitere Sachefor(arg in arguments)
funktioniert im IE nicht. Ich ersetzte durchfor (arg = 0; arg <arguments.length; arg++)
for...in
funktioniert nicht in jedem Browser, wie dieser Code es erwartet. Es werden alle aufzählbaren Eigenschaften durchlaufen, die in einigen Browsern enthalten sindarguments.length
, und in anderen werden die Argumente selbst überhaupt nicht enthalten sein. In jedem Fall, wennObject.prototype
hinzugefügt wird, werden wahrscheinlich alle Ergänzungen in der Gruppe enthalten sein. Der Code sollte eine Standardschleife verwendenfor
und nichtfor...in
.Ich möchte meine Lösung für das "Problem" teilen. Ich habe das Rad nicht neu erfunden, versuche aber, eine Lösung zu finden, die auf dem basiert, was JavaScript bereits tut. Der Vorteil ist, dass Sie alle impliziten Conversions kostenlos erhalten. Das Festlegen der Prototyp-Eigenschaft $ von String ergibt eine sehr schöne und kompakte Syntax (siehe Beispiele unten). Es ist vielleicht nicht der effizienteste Weg, aber in den meisten Fällen muss der Umgang mit der Ausgabe nicht besonders optimiert werden.
Hier einige Beispiele:
quelle
Ich werde meine eigenen Entdeckungen hinzufügen, die ich gefunden habe, seit ich gefragt habe:
Leider scheint Sprintf nicht mit der Formatierung von Tausendertrennzeichen wie dem .NET-Zeichenfolgenformat umzugehen.
quelle
Ich verwende eine kleine Bibliothek namens String.format für JavaScript, die die meisten Formatzeichenfolgenfunktionen (einschließlich des Formats von Zahlen und Datumsangaben) unterstützt und die .NET-Syntax verwendet. Das Skript selbst ist kleiner als 4 kB, sodass nicht viel Overhead entsteht.
quelle
Sehr elegant:
Kredit geht an
(defekter Link)https://gist.github.com/0i0/1519811quelle
{{0}}
und ähnliches behandelt{0}{1}.format("{1}", "{0}")
. Sollte ganz oben sein!Wenn Sie mit dem Tausendertrennzeichen umgehen möchten, sollten Sie toLocaleString () aus der JavaScript Number- Klasse verwenden, da dadurch die Zeichenfolge für die Region des Benutzers formatiert wird.
Die JavaScript- Datumsklasse kann lokalisierte Datums- und Uhrzeitangaben formatieren.
quelle
Das PHPJS-Projekt hat JavaScript-Implementierungen für viele der PHP-Funktionen geschrieben. Da die
sprintf()
Funktion von PHP im Wesentlichen mit der von C identisch istprintf()
, sollte die JavaScript-Implementierung Ihren Anforderungen entsprechen.quelle
Ich benutze dieses:
Dann nenne ich es:
quelle
Ich habe eine Lösung, die der von Peter sehr nahe kommt, aber sie befasst sich mit Zahlen- und Objektfällen.
Vielleicht könnte es sogar noch besser sein, sich mit allen tiefen Fällen zu befassen, aber für meine Bedürfnisse ist das in Ordnung.
PS: Diese Funktion ist sehr cool, wenn Sie Übersetzungen in Vorlagen-Frameworks wie AngularJS verwenden :
Wo das en.json so etwas ist
quelle
Eine etwas andere Version, die ich bevorzuge (diese verwendet {xxx} Token anstelle von {0} nummerierten Argumenten, dies ist viel selbstdokumentierender und passt viel besser zur Lokalisierung):
Eine Variation wäre:
das ruft zuerst eine l () -Lokalisierungsfunktion auf.
quelle
Es gibt "sprintf" für JavaScript, das Sie unter http://www.webtoolkit.info/javascript-sprintf.html finden .
quelle
Für diejenigen, die Node.JS und seine
util.format
Funktion mögen , habe ich es gerade in seine Vanille-JavaScript-Form extrahiert (mit nur Funktionen, die util.format verwendet):Geerntet von: https://github.com/joyent/node/blob/master/lib/util.js
quelle
Für die grundlegende Formatierung:
quelle
Ich habe einen etwas längeren Formatierer für JavaScript hier ...
Sie können auf verschiedene Arten formatieren:
String.format(input, args0, arg1, ...)
String.format(input, obj)
"literal".format(arg0, arg1, ...)
"literal".format(obj)
Wenn Sie ein ObjectBase.prototype.format (z. B. mit DateJS ) angegeben haben, wird dieses verwendet.
Beispiele ...
Ich habe auch einen Alias mit .asFormat erstellt und eine Erkennung eingerichtet, falls bereits ein string.format vorhanden ist (z. B. mit MS Ajax Toolkit (ich hasse diese Bibliothek).
quelle
Nur für den Fall, dass jemand eine Funktion benötigt, um die Verschmutzung des globalen Bereichs zu verhindern, ist hier die Funktion, die dasselbe tut:
quelle
Wir können eine einfache, leichte String.Format- String-Operationsbibliothek für Typescript verwenden.
String.Format ():
Zeichenfolgenformat für Bezeichner:
Zeichenfolgenformat für Objekte einschließlich Bezeichner:
quelle
Ich habe die
String.format
Variante nicht gesehen :quelle
Zur Verwendung mit jQuery.ajax () Erfolgsfunktionen. Übergeben Sie nur ein einziges Argument und ersetzen Sie die Zeichenfolge durch die Eigenschaften dieses Objekts als {propertyName}:
Beispiel:
quelle