Szukam dobrego odpowiednika JavaScript dla C / PHP printf()
lub dla programistów C # / Java String.Format()
( IFormatProvider
dla .NET).
Moje podstawowe wymaganie to na razie format separatora tysięcy dla liczb, ale dobrze byłoby coś, co obsługuje wiele kombinacji (łącznie z datami).
Zdaję sobie sprawę, że biblioteka Ajax Microsoftu zawiera wersję String.Format()
, ale nie chcemy całego narzutu tego frameworka.
javascript
printf
string.format
Chris S.
źródło
źródło
Odpowiedzi:
Od wersji ES6 możesz używać ciągów szablonów:
Zobacz szczegóły odpowiedzi Kim poniżej.
Inaczej:
Spróbuj sprintf () dla JavaScript .
Jeśli naprawdę chcesz samodzielnie wykonać prostą metodę formatowania, nie rób zamienników kolejno, ale rób to jednocześnie.
Ponieważ większość innych wymienionych propozycji kończy się niepowodzeniem, gdy ciąg zastępujący poprzedniej zamiany zawiera również sekwencję formatowania taką jak ta:
Normalnie można oczekiwać, że wynik będzie,
{1}{0}
ale rzeczywisty wynik to{1}{1}
. Więc rób jednocześnie zamianę, jak w sugestii strachu .źródło
num.toFixed()
metoda może wystarczyć!sprintf() for JavaScript
nie było dostępne.underscore.string
ma więcej funkcji oprócz sprintf, który jest oparty nasprintf() for JavaScript
implementacji. Poza tym biblioteka to zupełnie inny projekt.Opierając się na wcześniej sugerowanych rozwiązaniach:
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
wyjścia
Jeśli wolisz nie modyfikować
String
prototypu:Daje ci znacznie bardziej znane:
String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');
z tym samym wynikiem:
źródło
+
-operatora), pamiętaj o umieszczeniu całego łańcucha w nawiasach:("asd {0}"+"fas {1}").format("first", "second");
W przeciwnym razie funkcja zostanie zastosowana tylko do ostatniego łańcucha, który został dołączony.'foo {0}'.format(fnWithNoReturnValue())
. Obecnie wrócifoo {0}
. Po wprowadzeniu zmian wrócifoo undefined
.To zabawne, ponieważ Stack Overflow faktycznie ma własną funkcję formatowania
String
zwanego prototypemformatUnicorn
. Spróbuj! Wejdź do konsoli i wpisz coś takiego:Otrzymasz ten wynik:
Hello, Gabriel, are you feeling OK?
Jako argumentów możesz używać obiektów, tablic i ciągów! Mam jego kod i przerobiłem go, aby utworzyć nową wersję
String.prototype.format
:Zwróć uwagę na sprytne
Array.prototype.slice.call(arguments)
wywołanie - oznacza to, że jeśli wrzucisz argumenty, które są ciągami lub liczbami, a nie pojedynczym obiektem w stylu JSON,String.Format
zachowanie C # jest prawie dokładne.To dlatego, że
Array
nic nieslice
zmusi wszystko co warguments
w produktArray
, czy to pierwotnie, czy nie, ikey
będzie indeks (0, 1, 2 ...) każdego elementu tablicy zmuszane do łańcucha (na przykład «0», a więc"\\{0\\}"
dla pierwszego wzorca wyrażenia regularnego).Schludny.
źródło
g
), która może zastąpić ten sam klucz więcej niż jeden raz. W powyższym przykładzie możesz użyć{name}
wiele razy w tym samym zdaniu i wszystkie je zastąpić.name
jest"blah {adjective} blah"
?Formatowanie liczb w JavaScript
Doszedłem do tej strony pytań, mając nadzieję na znalezienie sposobu formatowania liczb w JavaScript, bez wprowadzania kolejnej biblioteki. Oto, co znalazłem:
Zaokrąglanie liczb zmiennoprzecinkowych
Wydaje się, że odpowiednikiem
sprintf("%.2f", num)
w JavaScript jestnum.toFixed(2)
formatowanienum
do 2 miejsc po przecinku z zaokrąglaniem (ale patrz komentarz @ ars265 na tematMath.round
poniżej).Forma wykładnicza
Odpowiednikiem
sprintf("%.2e", num)
jestnum.toExponential(2)
.Podstawy szesnastkowe i inne
Aby wydrukować liczby w bazie B, spróbuj
num.toString(B)
. JavaScript obsługuje automatyczną konwersję do i od zasad od 2 do 36 (ponadto niektóre przeglądarki mają ograniczoną obsługę kodowania base64 ).Strony referencyjne
Szybki samouczek na temat formatowania liczb JS
Strona referencyjna Mozilla dla toFixed () (z linkami do toPrecision (), toExponential (), toLocaleString (), ...)
źródło
..
działa również:33333..toExponential(2);
Od wersji ES6 możesz używać ciągów szablonów :
Należy pamiętać, że ciągi szablonów są otoczone znakami wstecznymi `zamiast (pojedynczych) cudzysłowów.
W celu uzyskania dalszych informacji:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Uwaga: Sprawdź stronę mozilla, aby znaleźć listę obsługiwanych przeglądarek.
źródło
const compile = (x, y) => `I can call this template string whenever I want.. x=${x}, y=${y}`
...compile(30, 20)
jsxt, Zippo
Ta opcja pasuje lepiej.
Dzięki tej opcji mogę zastąpić ciągi takie jak te:
Z twoim kodem drugi {0} nie zostałby zastąpiony. ;)
źródło
Używam tej prostej funkcji:
Jest to bardzo podobne do string.format:
źródło
+=
? powinienemformatted = this.replace("{" + arg + "}", arguments[arg]);
for...in
nie będzie działać w każdej przeglądarce, ponieważ oczekuje tego kod. Pętla obejmie wszystkie wyliczalne właściwości, które w niektórych przeglądarkach będą zawieraćarguments.length
, a w innych nawet nie uwzględni samych argumentów. W każdym razie, jeśliObject.prototype
zostanie dodany do, wszelkie dodatki prawdopodobnie zostaną zawarte w grupie. Kod powinien używać standardowejfor
pętli zamiastfor...in
."{0} is dead, but {1} is alive!".format("{1}", "ASP.NET") === "ASP.NET is dead, but ASP.NET is alive!"
arg
ma charakter globalny. Musisz to zrobić zamiast tego:for (var arg in arguments) {
Dla użytkowników Node.js istnieje
util.format
funkcja podobna do printf:źródło
%-20s %5.2f
)Dziwię się, że nikt tego nie używał
reduce
, jest to natywna zwięzła i potężna funkcja JavaScript.ES6 (EcmaScript2015)
<ES6
Jak to działa:
źródło
printf
funkcji: jsfiddle.net/11szrbx9(...a) => {return a.reduce((p: string, c: any) => p.replace(/%s/, c));
String.prototype.format
w ES6:((a,b,c)=>`${a}, ${b} and ${c}`)(...['me', 'myself', 'I'])
(zauważ, że jest to trochę zbędne, aby lepiej pasować do twojego przykładu)printf
specyfikatorów typów i dołączyć logikę do przedrostków wypełniania. Wydaje się, że iteracja po łańcuchu formatu w rozsądny sposób jest niewielkim wyzwaniem, imho. Świetne rozwiązanie, jeśli potrzebujesz tylko zamiany łańcucha.Oto minimalna implementacja sprintf w JavaScript: robi to tylko „% s” i „% d”, ale zostawiłem miejsce na rozszerzenie. Jest to bezużyteczne dla OP, ale inne osoby, które natkną się na ten wątek pochodzący od Google, mogą z niego skorzystać.
Przykład:
W przeciwieństwie do podobnych rozwiązań w poprzednich odpowiedziach, ta dokonuje wszystkich zamian za jednym razem , więc nie zastąpi części wcześniej zastąpionych wartości.
źródło
Programiści JavaScript mogą używać String.prototype.sprintf pod adresem https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js . Poniżej znajduje się przykład:
źródło
Dodając do
zippoxer
odpowiedzi, używam tej funkcji:Mam również nieprototypową wersję, której używam częściej ze względu na jej składnię podobną do języka Java:
Aktualizacja ES 2015
Wszystkie nowe, fajne rzeczy w ES 2015 sprawiają, że jest to o wiele łatwiejsze:
Uznałem, że ponieważ tak jak starsze, tak naprawdę nie analizuje liter, równie dobrze może użyć tylko jednego tokena
%%
. Ma to tę zaletę, że jest oczywiste i nie utrudnia korzystania z jednego%
. Jeśli jednak%%
z jakiegoś powodu potrzebujesz, musisz go zastąpić samym:źródło
+1 Zippo z wyjątkiem tego, że treść funkcji musi być taka, jak poniżej, w przeciwnym razie dołącza bieżący ciąg na każdej iteracji:
źródło
'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');
którym staje się wynikThe ASP is dead. Don't code {0}. Code PHP that is open source!
. Jeszcze jedna rzeczfor(arg in arguments)
nie działa w IE. Zastąpiłemfor (arg = 0; arg <arguments.length; arg++)
for...in
nie będzie działać w każdej przeglądarce, ponieważ oczekuje tego kod. Pętla obejmie wszystkie wyliczalne właściwości, które w niektórych przeglądarkach będą zawieraćarguments.length
, a w innych nawet nie uwzględni samych argumentów. W każdym razie, jeśliObject.prototype
zostanie dodany do, wszelkie dodatki prawdopodobnie zostaną zawarte w grupie. Kod powinien używać standardowejfor
pętli zamiastfor...in
.Chcę podzielić się moim rozwiązaniem problemu. Nie wynalazłem koła na nowo, ale próbuję znaleźć rozwiązanie oparte na tym, co już robi JavaScript. Zaletą jest to, że wszystkie niejawne konwersje są bezpłatne. Ustawienie właściwości prototypowej $ String daje bardzo ładną i zwartą składnię (patrz przykłady poniżej). Być może nie jest to najskuteczniejszy sposób, ale w większości przypadków w przypadku produkcji nie musi ona być superoptymalizowana.
Oto kilka przykładów:
źródło
Dodam własne odkrycia, które znalazłem odkąd zapytałem:
Niestety wydaje się, że sprintf nie obsługuje formatowania tysięcy separatorów, takich jak format ciągów .NET.
źródło
Korzystam z małej biblioteki o nazwie String.format dla JavaScript, która obsługuje większość możliwości formatowania ciągu znaków (w tym formatu liczb i dat) i wykorzystuje składnię .NET. Sam skrypt jest mniejszy niż 4 kB, więc nie powoduje dużego obciążenia.
źródło
Bardzo elegancko:
Kredyt trafia do
(uszkodzony link)https://gist.github.com/0i0/1519811źródło
{{0}}
a także takie rzeczy{0}{1}.format("{1}", "{0}")
. Powinien być na samym szczycie!Jeśli chcesz obsłużyć separator tysięcy, naprawdę powinieneś użyć metody toLocaleString () z klasy JavaScript Number, ponieważ sformatuje ona ciąg dla regionu użytkownika.
Klasa daty JavaScript może formatować zlokalizowane daty i godziny.
źródło
Projekt PHPJS napisał implementacje JavaScript dla wielu funkcji PHP. Ponieważ
sprintf()
funkcja PHP jest zasadniczo taka sama jak w języku Cprintf()
, ich implementacja JavaScript powinna zaspokoić twoje potrzeby.źródło
Używam tego:
Następnie nazywam to:
źródło
Mam rozwiązanie bardzo zbliżone do rozwiązania Petera, ale dotyczy ono liczby i przypadku.
Może lepiej byłoby zajmować się wszystkimi najgłębszymi sprawami, ale dla moich potrzeb jest to w porządku.
PS: Ta funkcja jest bardzo fajna, jeśli używasz tłumaczeń w ramach szablonów, takich jak AngularJS :
Gdzie jest en.json
źródło
Jedna nieco inna wersja, ta, którą preferuję (ta używa tokenów {xxx} zamiast numerowanych argumentów {0}, jest to o wiele bardziej samodokumentujące i lepiej pasuje do lokalizacji):
Wariant byłby:
która najpierw wywołuje funkcję lokalizacji l ().
źródło
Istnieje „sprintf” dla JavaScript, który można znaleźć na stronie http://www.webtoolkit.info/javascript-sprintf.html .
źródło
Dla tych, którzy lubią Node.JS i jego
util.format
funkcję, właśnie wyodrębniłem go do waniliowej formy JavaScript (tylko z funkcjami, które wykorzystuje use.format):Zebrane z: https://github.com/joyent/node/blob/master/lib/util.js
źródło
Do podstawowego formatowania:
źródło
Mam nieco dłuższy formatowania dla JavaScriptu tutaj ...
Możesz przeprowadzić formatowanie na kilka sposobów:
String.format(input, args0, arg1, ...)
String.format(input, obj)
"literal".format(arg0, arg1, ...)
"literal".format(obj)
Ponadto, jeśli powiesz ObjectBase.prototype.format (na przykład z DateJS ), użyje go.
Przykłady ...
Użyłem również aliasu z .asFormat i mam pewne wykrycie na wypadek, gdyby już istniał łańcuch. Format (np. Z MS Ajax Toolkit (nienawidzę tej biblioteki).
źródło
Na wypadek, gdyby ktoś potrzebował funkcji zapobiegającej zanieczyszczeniu zasięgu globalnego, oto funkcja, która robi to samo:
źródło
Możemy użyć prostej, lekkiej biblioteki operacji na łańcuchach znaków String.Format dla maszynopisu.
String.Format ():
Format ciągu dla specyfikatorów:
Format ciągu dla obiektów, w tym specyfikatory:
źródło
Nie widziałem
String.format
wariantu:źródło
Do użytku z funkcjami powodzenia jQuery.ajax (). Przekaż tylko jeden argument i ciąg znaków zamień na właściwości tego obiektu jako {propertyName}:
Przykład:
źródło