Vraag JavaScript-equivalent voor printf / String.Format


Ik ben op zoek naar een goed JavaScript-equivalent van de C / PHP printf() of voor C # / Java-programmeurs, String.Format() (IFormatProvider voor .NET).

Mijn basisvereiste is nu een duizendtal scheidingsteken voor getallen, maar iets dat veel combinaties (inclusief datums) verwerkt, zou goed zijn.

Ik besef dat van Microsoft Ajax bibliotheek biedt een versie van String.Format(), maar we willen niet de volledige overhead van dat raamwerk.


1605
2018-01-12 20:02


oorsprong


antwoorden:


Proberen sprintf () voor JavaScript.


BijwerkenOk, als je echt een eenvoudige formatiemethode op je eentje wilt doen, doe de vervangingen dan niet achter elkaar maar doe ze tegelijkertijd.

Omdat de meeste andere voorstellen die worden genoemd mislukken wanneer een vervangende tekenreeks van vorige vervanging ook een notatie als volgt bevat:

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

Normaal gesproken zou je verwachten dat de uitvoer dat is {1}{0} maar de daadwerkelijke uitvoer is {1}{1}. Dus doe gelijktijdig een vervanging in plaats van in de suggestie van fearphage.


684



Voortbouwen op de eerder voorgestelde oplossingen:

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

uitgangen

ASP is dood, maar ASP.NET leeft! ASP {2}


Als u liever niet wijzigt Stringhet prototype:

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

Geeft u het veel meer bekende:

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

met hetzelfde resultaat:

ASP is dood, maar ASP.NET leeft! ASP {2}


1278



Het is grappig omdat Stack Overflow eigenlijk zijn eigen opmaakfunctie heeft voor de String prototype genoemd formatUnicorn. Probeer het! Ga naar de console en typ zoiets als:

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

Firebug

Je krijgt deze output:

Hello, Gabriel, are you feeling OK?

U kunt objecten, arrays en reeksen als argumenten gebruiken! Ik heb de code gekregen en deze opnieuw bewerkt om een ​​nieuwe versie van te maken 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;
};

Let op de slimmerik Array.prototype.slice.call(arguments) call - dat betekent dat als je argumenten invoert die strings of getallen zijn, geen enkel object in JSON-stijl, je C # 's krijgt String.Format gedrag bijna precies.

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

Dat is omdat Array's slice zal dwingen wat er ook in zit arguments in een Array, of het oorspronkelijk was of niet, en de key is de index (0, 1, 2 ...) van elk arrayelement dat is afgedwongen tot een tekenreeks (bijv. "0", dus "\\{0\\}" voor je eerste regexp-patroon).

Netjes.


366



Nummeropmaak in JavaScript

Ik kwam op deze vraagpagina in de hoop te vinden hoe formaatnummers in JavaScript, zonder nog een andere bibliotheek te introduceren. Dit is wat ik heb gevonden:

Drijvende-kommagetallen afronden

Het equivalent van sprintf("%.2f", num) in JavaScript lijkt te zijn num.toFixed(2), welke formaten num tot op 2 decimalen, met afronding (maar zie de opmerking van @ ars265 over Math.round hieronder).

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

Exponentiële vorm

Het equivalent van sprintf("%.2e", num) is num.toExponential(2).

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

Hexadecimaal en andere basen

Om de getallen in basis B af te drukken, probeert u het num.toString(B). JavaScript ondersteunt automatische conversie van en naar basis 2 tot en met 36 (daarnaast hebben sommige browsers beperkte ondersteuning voor base64-codering).

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

Referentiepagina's

Snelle zelfstudie over JS-nummeropmaak

Mozilla-referentiepagina voor toFixed () (met koppelingen naar toPrecision (), toExponential (), toLocaleString (), ...)


288



jsxt, Zippo

Deze optie past beter.

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

Met deze optie kan ik strings als deze vervangen:

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

Met uw code zou de tweede {0} niet worden vervangen. ;)


168



Vanaf ES6 kunt u gebruiken sjabloonstrings:

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

Houd er rekening mee dat sjabloonstrings zijn omringd door backticks `in plaats van (enkele) aanhalingstekens.

Voor meer informatie:

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

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

Notitie: Bekijk de mozilla-site om een ​​lijst met ondersteunde browsers te vinden.


168



Ik gebruik deze eenvoudige functie:

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

Dat lijkt erg op string.format:

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

90



Hier is een minimaal implementatie van sprintf in JavaScript: het doet alleen "% s" en "% d", maar ik heb ruimte gelaten om het uit te breiden. Het is nutteloos voor het OP, maar andere mensen die deze draad van Google tegenkomen, kunnen hiervan profiteren.

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

Voorbeeld:

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

In tegenstelling tot vergelijkbare oplossingen in eerdere antwoorden, deze doet alle vervangingen in een keer, dus het zal geen delen van eerder vervangen waarden vervangen.


48



Voor Node.js gebruikers is er util.format welke printf-achtige functionaliteit heeft:

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

45



Ik ben verrast dat niemand heeft gebruikt reduce, dit is een native, beknopte en krachtige JavaScript-functie.

ES6 (EcmaScript2015)

String.prototype.format = function() {
  return [...arguments].reduce((p,c) => p.replace(/%s/,c), this);
};

console.log('Is that a %s or a %s?... No, it\'s %s!'.format('plane', 'bird', 'SOman'));

<ES6

function interpolate(theString, argumentArray) {
    var regex = /%s/;
    var _r=function(p,c){return p.replace(regex,c);}
    return argumentArray.reduce(_r, theString);
}

interpolate("%s, %s and %s", ["Me", "myself", "I"]); // "Me, myself and I"

Hoe het werkt:

verminderen past een functie toe op een accumulator en elk element in de array (van links naar rechts) om deze tot één waarde te reduceren.

var _r= function(p,c){return p.replace(/%s/,c)};

console.log(
  ["a", "b", "c"].reduce(_r, "[%s], [%s] and [%s]") + '\n',
  [1, 2, 3].reduce(_r, "%s+%s=%s") + '\n',
  ["cool", 1337, "stuff"].reduce(_r, "%s %s %s")
);


36



JavaScript-programmeurs kunnen String.prototype.sprintf gebruiken op https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js. Hieronder is een voorbeeld:

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

30