JavaScript equivalent aan printf/String.Format

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

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

Ik realiseer me dat de Ajax-bibliotheek van Microsoft een versie van String.Format(), maar we willen niet de volledige overhead van dat framework.


Antwoord 1, autoriteit 100%

Huidige JavaScript

Vanaf ES6 zou je template strings kunnen gebruiken:

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

Zie het antwoordvan Kim hieronder voor meer informatie.


Ouder antwoord

Probeer sprintf() voor JavaScript.


Als je echt zelf een eenvoudige formatteringsmethode wilt doen, voer de vervangingen dan niet achter elkaar uit, maar doe ze tegelijkertijd.

Omdat de meeste van de andere genoemde voorstellen mislukken wanneer een vervangreeks van de vorige vervanging ook een opmaakreeks als deze bevat:

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

Normaal gesproken zou je verwachten dat de uitvoer {1}{0}is, maar de werkelijke uitvoer is {1}{1}. Dus doe in plaats daarvan een gelijktijdige vervanging zoals in suggestie van Fearphage.


Antwoord 2, autoriteit 99%

Voortbouwend 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 je het prototype van Stringliever niet wilt wijzigen:

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 bekendere:

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}


Antwoord 3, autoriteit 41%

Het is grappig omdat Stack Overflow hun eigen opmaakfunctie heeft voor het String-prototype genaamd formatUnicorn. Probeer het! Ga naar de console en typ iets 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 strings als argumenten gebruiken! Ik kreeg de code en herwerkte het om een ​​nieuwe versie van String.prototype.formatte produceren:

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 slimme Array.prototype.slice.call(arguments)-aanroep — dat betekent dat als je argumenten invoert die strings of cijfers zijn, geen enkel JSON-achtig object, je C#’s krijgt String.Formatgedrag bijna exact.

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

Dat komt omdat de slicevan slicealles wat in argumentsstaat, in een slicezal forceren, of het nu oorspronkelijk was of niet, en de keyzal de index (0, 1, 2…) zijn van elk array-element dat in een string wordt gedwongen (bijv. “0”, dus "\\{0\\}"voor uw eerste regexp-patroon).

Netjes.


Antwoord 4, autoriteit 25%

Getalnotatie in JavaScript

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

Drijvende-kommagetallen afronden

Het equivalent van sprintf("%.2f", num)in JavaScript lijkt num.toFixed(2)te zijn, dat numtot op 2 decimalen, met afronding (maar zie de opmerking van @ars265 over Math.roundhieronder).

(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

Probeer num.toString(B)om getallen in basis B af te drukken. JavaScript ondersteunt automatische conversie van en naar bases 2 tot en met 36 (bovendien 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 links to toPrecision(), toExponential(), toLocaleString(), …)


Antwoord 5, autoriteit 20%

Vanaf ES6 zou je sjabloonstringskunnen gebruiken:

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

Houd er rekening mee dat sjabloontekenreeksen omringd zijn 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/Referentie/template_strings

Opmerking:
Kijk op de mozilla-site voor een lijst met ondersteunde browsers.


Antwoord 6, autoriteit 13%

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. 😉


Antwoord 7, autoriteit 9%

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

Antwoord 8, autoriteit 6%

Voor Node.js-gebruikers is er util.formatmet printf-achtige functionaliteit:

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

Antwoord 9, autoriteit 4%

Het verbaast me dat niemand 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'));

Antwoord 10, autoriteit 4%

Hier is een minimaleimplementatie van sprintf in JavaScript: het doet alleen “%s” en “%d”, maar ik heb ruimte overgelaten om het uit te breiden. Het is nutteloos voor de OP, maar andere mensen die deze thread van Google tegenkomen, kunnen er baat bij hebben.

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, doet deze alle vervangingen in één keer, dus het zal geen delen van eerder vervangen waarden vervangen.


Antwoord 11, autoriteit 2%

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

Antwoord 12, autoriteit 2%

Toevoegen aan zippoxer‘s antwoord, gebruik ik deze functie:

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.

Ik heb ook een niet-prototypeversie die ik vaker gebruik vanwege de Java-achtige syntaxis:

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-update

Alle coole nieuwe dingen in ES 2015 maken dit een stuk eenvoudiger:

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."

Ik dacht dat, aangezien dit, net als de oudere, de letters niet echt worden geparseerd, het net zo goed een enkele token %%kan gebruiken. Dit heeft het voordeel dat het duidelijk is en het niet moeilijk maakt om een ​​enkele %te gebruiken. Als u echter om de een of andere reden %%nodig heeft, moet u het door zichzelf vervangen:

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

Antwoord 13, autoriteit 2%

Ik wil mijn oplossing voor het ‘probleem’ delen. Ik heb het wiel niet opnieuw uitgevonden, maar probeer een oplossing te vinden op basis van wat JavaScript al doet. Het voordeel is dat u alle impliciete conversies gratis krijgt. Het instellen van de prototype-eigenschap $ van String geeft een zeer mooie en compacte syntaxis (zie onderstaande voorbeelden). Het is misschien niet de meest efficiënte manier, maar in de meeste gevallen hoeft het met output niet super geoptimaliseerd te zijn.

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 zijn een paar voorbeelden:

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'

Antwoord 14, autoriteit 2%

+1 Zippo met de uitzondering dat de hoofdtekst van de functie moet zijn zoals hieronder of anders wordt de huidige tekenreeks bij elke iteratie toegevoegd:

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

Antwoord 15

Ik zal mijn eigen ontdekkingen toevoegen die ik heb gevonden sinds ik erom vroeg:

Helaas lijkt het erop dat sprintf de opmaak van duizend scheidingstekens niet aankan, zoals het tekenreeksformaat van .NET.


Antwoord 16

Ik gebruik een kleine bibliotheek genaamd String.format voor JavaScriptdie het grootste deel van het formaat ondersteunt tekenreeksmogelijkheden (inclusief het formaat van getallen en datums), en gebruikt de .NET-syntaxis. Het script zelf is kleiner dan 4 kB, dus het zorgt niet voor veel overhead.


Antwoord 17

Zeer elegant:

String.prototype.format = function (){
    var args = arguments;
    return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (curlyBrack, index) {
        return ((curlyBrack == "{{") ? "{" : ((curlyBrack == "}}") ? "}" : args[index]));
    });
};
// Usage:
"{0}{1}".format("{1}", "{0}")

Krediet gaat naar (gebroken link)https://gist.github.com/0i0/1519811


Antwoord 18

Als u het scheidingsteken voor duizendtallen wilt gebruiken, moet u echt toLocaleString() gebruiken uit het JavaScript Numberclass omdat het de tekenreeks opmaakt voor de regio van de gebruiker.

De JavaScript-klasse Datekan gelokaliseerde datums en tijden opmaken.


Antwoord 19

Er is “sprintf” voor JavaScript die je kunt vinden op http://www.webtoolkit .info/javascript-sprintf.html.


Antwoord 20

Het PHPJS-projectheeft JavaScript-implementaties geschreven voor veel van de functies van PHP. Aangezien PHP’s sprintf()functie in principe hetzelfde is als C’s printf(), hun JavaScript-implementatie ervanzou aan uw behoeften moeten voldoen.


Antwoord 21

Ik gebruik deze:

String.prototype.format = function() {
    var newStr = this, i = 0;
    while (/%s/.test(newStr))
        newStr = newStr.replace("%s", arguments[i++])
    return newStr;
}

Dan noem ik het:

"<h1>%s</h1><p>%s</p>".format("Header", "Just a test!");

Antwoord 22

Ik heb een oplossing die heel dicht bij die van Peter ligt, maar die gaat over het geval van getallen en objecten.

if (!String.prototype.format) {
  String.prototype.format = function() {
    var args;
    args = arguments;
    if (args.length === 1 && args[0] !== null && typeof args[0] === 'object') {
      args = args[0];
    }
    return this.replace(/{([^}]*)}/g, function(match, key) {
      return (typeof args[key] !== "undefined" ? args[key] : match);
    });
  };
}

Misschien zou het nog beter kunnen zijn om alle diepgaande zaken af ​​te handelen, maar voor mijn behoeften is dit prima.

"This is an example from {name}".format({name:"Blaine"});
"This is an example from {0}".format("Blaine");

PS: Deze functie is erg cool als je vertalingen gebruikt in template-frameworks zoals AngularJS:

<h1> {{('hello-message'|translate).format(user)}} <h1>
<h1> {{('hello-by-name'|translate).format( user ? user.name : 'You' )}} <h1>

Waar de en.json zoiets is

{
    "hello-message": "Hello {name}, welcome.",
    "hello-by-name": "Hello {0}, welcome."
}

Antwoord 23

Een heel iets andere versie, degene die ik prefereer (deze gebruikt {xxx} tokens in plaats van {0} genummerde argumenten, dit is veel meer zelfdocumenterend en past veel beter bij de lokalisatie):

String.prototype.format = function(tokens) {
  var formatted = this;
  for (var token in tokens)
    if (tokens.hasOwnProperty(token))
      formatted = formatted.replace(RegExp("{" + token + "}", "g"), tokens[token]);
  return formatted;
};

Een variatie zou zijn:

 var formatted = l(this);

die eerst een l()-lokalisatiefunctie aanroept.


Antwoord 24

Voor basisopmaak:

var template = jQuery.validator.format("{0} is not a valid value");
var result = template("abc");

Antwoord 25

Ik heb een iets langere formatter voor JavaScript hier

Je kunt op verschillende manieren formatteren:

  • String.format(input, args0, arg1, ...)
  • String.format(input, obj)
  • "literal".format(arg0, arg1, ...)
  • "literal".format(obj)

Ook als je een ObjectBase.prototype.format hebt (zoals met DateJS), zal het dat.

Voorbeelden…

var input = "numbered args ({0}-{1}-{2}-{3})";
console.log(String.format(input, "first", 2, new Date()));
//Outputs "numbered args (first-2-Thu May 31 2012...Time)-{3})"
console.log(input.format("first", 2, new Date()));
//Outputs "numbered args(first-2-Thu May 31 2012...Time)-{3})"
console.log(input.format(
    "object properties ({first}-{second}-{third:yyyy-MM-dd}-{fourth})"
    ,{
        'first':'first'
        ,'second':2
        ,'third':new Date() //assumes Date.prototype.format method
    }
));
//Outputs "object properties (first-2-2012-05-31-{3})"

Ik heb ook een alias gebruikt met .asFormat en heb enige detectie voor het geval er al een string.format is (zoals met MS Ajax Toolkit (ik haat die bibliotheek).


Antwoord 26

Voor het geval iemand een functie nodig heeft om vervuiling van de wereld te voorkomen, hier is de functie die hetzelfde doet:

 function _format (str, arr) {
    return str.replace(/{(\d+)}/g, function (match, number) {
      return typeof arr[number] != 'undefined' ? arr[number] : match;
    });
  };

Antwoord 27

Voor degenen die houden van Node.JSen zijn util.format-functie, ik heb het zojuist uitgepakt in zijn vanille JavaScript-vorm (met alleen functies die util.format gebruikt):

exports = {};
function isString(arg) {
    return typeof arg === 'string';
}
function isNull(arg) {
    return arg === null;
}
function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
}
function isBoolean(arg) {
    return typeof arg === 'boolean';
}
function isUndefined(arg) {
    return arg === void 0;
}
function stylizeNoColor(str, styleType) {
    return str;
}
function stylizeWithColor(str, styleType) {
    var style = inspect.styles[styleType];
    if (style) {
        return '\u001b[' + inspect.colors[style][0] + 'm' + str +
            '\u001b[' + inspect.colors[style][3] + 'm';
    } else {
        return str;
    }
}
function isFunction(arg) {
    return typeof arg === 'function';
}
function isNumber(arg) {
    return typeof arg === 'number';
}
function isSymbol(arg) {
    return typeof arg === 'symbol';
}
function formatPrimitive(ctx, value) {
    if (isUndefined(value))
        return ctx.stylize('undefined', 'undefined');
    if (isString(value)) {
        var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                .replace(/'/g, "\\'")
                .replace(/\\"/g, '"') + '\'';
        return ctx.stylize(simple, 'string');
    }
    if (isNumber(value)) {
        // Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
        // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
        if (value === 0 && 1 / value < 0)
            return ctx.stylize('-0', 'number');
        return ctx.stylize('' + value, 'number');
    }
    if (isBoolean(value))
        return ctx.stylize('' + value, 'boolean');
    // For some reason typeof null is "object", so special case here.
    if (isNull(value))
        return ctx.stylize('null', 'null');
    // es6 symbol primitive
    if (isSymbol(value))
        return ctx.stylize(value.toString(), 'symbol');
}
function arrayToHash(array) {
    var hash = {};
    array.forEach(function (val, idx) {
        hash[val] = true;
    });
    return hash;
}
function objectToString(o) {
    return Object.prototype.toString.call(o);
}
function isDate(d) {
    return isObject(d) && objectToString(d) === '[object Date]';
}
function isError(e) {
    return isObject(e) &&
        (objectToString(e) === '[object Error]' || e instanceof Error);
}
function isRegExp(re) {
    return isObject(re) && objectToString(re) === '[object RegExp]';
}
function formatError(value) {
    return '[' + Error.prototype.toString.call(value) + ']';
}
function formatPrimitiveNoColor(ctx, value) {
    var stylize = ctx.stylize;
    ctx.stylize = stylizeNoColor;
    var str = formatPrimitive(ctx, value);
    ctx.stylize = stylize;
    return str;
}
function isArray(ar) {
    return Array.isArray(ar);
}
function hasOwnProperty(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
    var name, str, desc;
    desc = Object.getOwnPropertyDescriptor(value, key) || {value: value[key]};
    if (desc.get) {
        if (desc.set) {
            str = ctx.stylize('[Getter/Setter]', 'special');
        } else {
            str = ctx.stylize('[Getter]', 'special');
        }
    } else {
        if (desc.set) {
            str = ctx.stylize('[Setter]', 'special');
        }
    }
    if (!hasOwnProperty(visibleKeys, key)) {
        name = '[' + key + ']';
    }
    if (!str) {
        if (ctx.seen.indexOf(desc.value) < 0) {
            if (isNull(recurseTimes)) {
                str = formatValue(ctx, desc.value, null);
            } else {
                str = formatValue(ctx, desc.value, recurseTimes - 1);
            }
            if (str.indexOf('\n') > -1) {
                if (array) {
                    str = str.split('\n').map(function (line) {
                        return '  ' + line;
                    }).join('\n').substr(2);
                } else {
                    str = '\n' + str.split('\n').map(function (line) {
                        return '   ' + line;
                    }).join('\n');
                }
            }
        } else {
            str = ctx.stylize('[Circular]', 'special');
        }
    }
    if (isUndefined(name)) {
        if (array && key.match(/^\d+$/)) {
            return str;
        }
        name = JSON.stringify('' + key);
        if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
            name = name.substr(1, name.length - 2);
            name = ctx.stylize(name, 'name');
        } else {
            name = name.replace(/'/g, "\\'")
                .replace(/\\"/g, '"')
                .replace(/(^"|"$)/g, "'")
                .replace(/\\\\/g, '\\');
            name = ctx.stylize(name, 'string');
        }
    }
    return name + ': ' + str;
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
    var output = [];
    for (var i = 0, l = value.length; i < l; ++i) {
        if (hasOwnProperty(value, String(i))) {
            output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
                String(i), true));
        } else {
            output.push('');
        }
    }
    keys.forEach(function (key) {
        if (!key.match(/^\d+$/)) {
            output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
                key, true));
        }
    });
    return output;
}
function reduceToSingleString(output, base, braces) {
    var length = output.reduce(function (prev, cur) {
        return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
    }, 0);
    if (length > 60) {
        return braces[0] +
            (base === '' ? '' : base + '\n ') +
            ' ' +
            output.join(',\n  ') +
            ' ' +
            braces[1];
    }
    return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
function formatValue(ctx, value, recurseTimes) {
    // Provide a hook for user-specified inspect functions.
    // Check that value is an object with an inspect function on it
    if (ctx.customInspect &&
        value &&
        isFunction(value.inspect) &&
            // Filter out the util module, it's inspect function is special
        value.inspect !== exports.inspect &&
            // Also filter out any prototype objects using the circular check.
        !(value.constructor && value.constructor.prototype === value)) {
        var ret = value.inspect(recurseTimes, ctx);
        if (!isString(ret)) {
            ret = formatValue(ctx, ret, recurseTimes);
        }
        return ret;
    }
    // Primitive types cannot have properties
    var primitive = formatPrimitive(ctx, value);
    if (primitive) {
        return primitive;
    }
    // Look up the keys of the object.
    var keys = Object.keys(value);
    var visibleKeys = arrayToHash(keys);
    if (ctx.showHidden) {
        keys = Object.getOwnPropertyNames(value);
    }
    // This could be a boxed primitive (new String(), etc.), check valueOf()
    // NOTE: Avoid calling `valueOf` on `Date` instance because it will return
    // a number which, when object has some additional user-stored `keys`,
    // will be printed out.
    var formatted;
    var raw = value;
    try {
        // the .valueOf() call can fail for a multitude of reasons
        if (!isDate(value))
            raw = value.valueOf();
    } catch (e) {
        // ignore...
    }
    if (isString(raw)) {
        // for boxed Strings, we have to remove the 0-n indexed entries,
        // since they just noisey up the output and are redundant
        keys = keys.filter(function (key) {
            return !(key >= 0 && key < raw.length);
        });
    }
    // Some type of object without properties can be shortcutted.
    if (keys.length === 0) {
        if (isFunction(value)) {
            var name = value.name ? ': ' + value.name : '';
            return ctx.stylize('[Function' + name + ']', 'special');
        }
        if (isRegExp(value)) {
            return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        }
        if (isDate(value)) {
            return ctx.stylize(Date.prototype.toString.call(value), 'date');
        }
        if (isError(value)) {
            return formatError(value);
        }
        // now check the `raw` value to handle boxed primitives
        if (isString(raw)) {
            formatted = formatPrimitiveNoColor(ctx, raw);
            return ctx.stylize('[String: ' + formatted + ']', 'string');
        }
        if (isNumber(raw)) {
            formatted = formatPrimitiveNoColor(ctx, raw);
            return ctx.stylize('[Number: ' + formatted + ']', 'number');
        }
        if (isBoolean(raw)) {
            formatted = formatPrimitiveNoColor(ctx, raw);
            return ctx.stylize('[Boolean: ' + formatted + ']', 'boolean');
        }
    }
    var base = '', array = false, braces = ['{', '}'];
    // Make Array say that they are Array
    if (isArray(value)) {
        array = true;
        braces = ['[', ']'];
    }
    // Make functions say that they are functions
    if (isFunction(value)) {
        var n = value.name ? ': ' + value.name : '';
        base = ' [Function' + n + ']';
    }
    // Make RegExps say that they are RegExps
    if (isRegExp(value)) {
        base = ' ' + RegExp.prototype.toString.call(value);
    }
    // Make dates with properties first say the date
    if (isDate(value)) {
        base = ' ' + Date.prototype.toUTCString.call(value);
    }
    // Make error with message first say the error
    if (isError(value)) {
        base = ' ' + formatError(value);
    }
    // Make boxed primitive Strings look like such
    if (isString(raw)) {
        formatted = formatPrimitiveNoColor(ctx, raw);
        base = ' ' + '[String: ' + formatted + ']';
    }
    // Make boxed primitive Numbers look like such
    if (isNumber(raw)) {
        formatted = formatPrimitiveNoColor(ctx, raw);
        base = ' ' + '[Number: ' + formatted + ']';
    }
    // Make boxed primitive Booleans look like such
    if (isBoolean(raw)) {
        formatted = formatPrimitiveNoColor(ctx, raw);
        base = ' ' + '[Boolean: ' + formatted + ']';
    }
    if (keys.length === 0 && (!array || value.length === 0)) {
        return braces[0] + base + braces[1];
    }
    if (recurseTimes < 0) {
        if (isRegExp(value)) {
            return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        } else {
            return ctx.stylize('[Object]', 'special');
        }
    }
    ctx.seen.push(value);
    var output;
    if (array) {
        output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
    } else {
        output = keys.map(function (key) {
            return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
        });
    }
    ctx.seen.pop();
    return reduceToSingleString(output, base, braces);
}
function inspect(obj, opts) {
    // default options
    var ctx = {
        seen: [],
        stylize: stylizeNoColor
    };
    // legacy...
    if (arguments.length >= 3) ctx.depth = arguments[2];
    if (arguments.length >= 4) ctx.colors = arguments[3];
    if (isBoolean(opts)) {
        // legacy...
        ctx.showHidden = opts;
    } else if (opts) {
        // got an "options" object
        exports._extend(ctx, opts);
    }
    // set default options
    if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
    if (isUndefined(ctx.depth)) ctx.depth = 2;
    if (isUndefined(ctx.colors)) ctx.colors = false;
    if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
    if (ctx.colors) ctx.stylize = stylizeWithColor;
    return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
    'bold': [1, 22],
    'italic': [3, 23],
    'underline': [4, 24],
    'inverse': [7, 27],
    'white': [37, 39],
    'grey': [90, 39],
    'black': [30, 39],
    'blue': [34, 39],
    'cyan': [36, 39],
    'green': [32, 39],
    'magenta': [35, 39],
    'red': [31, 39],
    'yellow': [33, 39]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
    'special': 'cyan',
    'number': 'yellow',
    'boolean': 'yellow',
    'undefined': 'grey',
    'null': 'bold',
    'string': 'green',
    'symbol': 'green',
    'date': 'magenta',
    // "name": intentionally not styling
    'regexp': 'red'
};
var formatRegExp = /%[sdj%]/g;
exports.format = function (f) {
    if (!isString(f)) {
        var objects = [];
        for (var j = 0; j < arguments.length; j++) {
            objects.push(inspect(arguments[j]));
        }
        return objects.join(' ');
    }
    var i = 1;
    var args = arguments;
    var len = args.length;
    var str = String(f).replace(formatRegExp, function (x) {
        if (x === '%%') return '%';
        if (i >= len) return x;
        switch (x) {
            case '%s':
                return String(args[i++]);
            case '%d':
                return Number(args[i++]);
            case '%j':
                try {
                    return JSON.stringify(args[i++]);
                } catch (_) {
                    return '[Circular]';
                }
            default:
                return x;
        }
    });
    for (var x = args[i]; i < len; x = args[++i]) {
        if (isNull(x) || !isObject(x)) {
            str += ' ' + x;
        } else {
            str += ' ' + inspect(x);
        }
    }
    return str;
};

Geoogst van: https://github.com/joyent/node/blob/master/ lib/util.js


Antwoord 28

We kunnen een eenvoudige lichtgewicht String.Formatstringbewerkingsbibliotheek gebruiken voor Typescript .

String.Format():

var id = image.GetId()
String.Format("image_{0}.jpg", id)
output: "image_2db5da20-1c5d-4f1a-8fd4-b41e34c8c5b5.jpg";

Tekenreeksindeling voor bestekschrijvers:

var value = String.Format("{0:L}", "APPLE"); //output "apple"
value = String.Format("{0:U}", "apple"); // output "APPLE"
value = String.Format("{0:d}", "2017-01-23 00:00"); //output "23.01.2017"
value = String.Format("{0:s}", "21.03.2017 22:15:01") //output "2017-03-21T22:15:01"
value = String.Format("{0:n}", 1000000);
//output "1.000.000"
value = String.Format("{0:00}", 1);
//output "01"

Tekenreeksindeling voor objecten inclusief specificaties:

var fruit = new Fruit();
fruit.type = "apple";
fruit.color = "RED";
fruit.shippingDate = new Date(2018, 1, 1);
fruit.amount = 10000;
String.Format("the {type:U} is {color:L} shipped on {shippingDate:s} with an amount of {amount:n}", fruit);
// output: the APPLE is red shipped on 2018-01-01 with an amount of 10.000

Antwoord 29

Ik zag pyformatniet in de lijst, dus ik dacht ik gooi het erbij :

console.log(pyformat( 'The {} {} jumped over the {}'
                , ['brown' ,'fox' ,'foobar']
                ))
console.log(pyformat('The {0} {1} jumped over the {1}'
                , ['brown' ,'fox' ,'foobar']
                ))
console.log(pyformat('The {color} {animal} jumped over the {thing}'
                , [] ,{color: 'brown' ,animal: 'fox' ,thing: 'foobaz'}
                ))

Antwoord 30

Met Lodashkunt u sjabloonfunctionaliteit verkrijgen:

Gebruik het letterlijke scheidingsteken van de ES-sjabloon als scheidingsteken voor “interpoleren”.
Schakel ondersteuning uit door het scheidingsteken “interpoleren” te vervangen.

var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4 + one =

Other episodes