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 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 String
liever 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"});
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.format
te 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.Format
gedrag bijna exact.
"a{0}bcd{1}ef".formatUnicorn("FOO", "BAR"); // yields "aFOObcdBARef"
Dat komt omdat de slice
van slice
alles wat in arguments
staat, in een slice
zal forceren, of het nu oorspronkelijk was of niet, en de key
zal 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 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
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.format
met 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!