JavaScript equivalent to printf/String.Format
我正在寻找一个相当于J/PHP EDCOX1的0 JavaScript或C/J/Java程序员EDCOX1×1(EDCOX1,2,.net)。
我现在的基本要求是对数字使用千位分隔符格式,但是处理许多组合(包括日期)的功能会很好。
我意识到微软的Ajax库提供了
基于先前建议的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 | // 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 ; }); }; } |
输出
ASP is dead, but ASP.NET is alive! ASP {2}
如果您不想修改
1 2 3 4 5 6 7 8 9 10 11 | 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 ; }); }; } |
让您更加熟悉:
结果相同:
ASP is dead, but ASP.NET is alive! ASP {2}
从上的ES6可以使用模板字符串:
1 2 3 | let soMany = 10; console.log(`This is ${soMany} times easier!`); //"This is 10 times easier! |
有关详细信息,请参阅下面的Kim答案。
否则:尝试sprintf()获取javascript。
如果你真的想自己做一个简单的格式方法,不要连续做替换,而是同时做替换。
因为当先前替换的替换字符串也包含这样的格式序列时,提到的大多数其他建议都失败了:
1 | "{0}{1}".format("{1}","{0}") |
通常,您希望输出为
这很有趣,因为堆栈溢出实际上对名为
1 | "Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective:"OK"}); |
你得到这个输出:
可以使用对象、数组和字符串作为参数!我得到了它的代码并对其进行了修改,以生成新版本的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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; }; |
注意,巧妙的
1 | "a{0}bcd{1}ef".formatUnicorn("foo","bar"); // yields"aFOObcdBARef" |
这是因为
整洁的
型javascript中的数字格式
我来到这个问题页面,希望找到如何用javascript格式化数字,而不引入另一个库。以下是我发现的:
四舍五入浮点数
在javascript中,与
1 2 | (12.345).toFixed(2); // returns"12.35" (rounding!) (12.3).toFixed(2); // returns"12.30" (zero padding) |
指数形式
与
1 | (33333).toExponential(2); //"3.33e+4" |
号十六进制和其他基
要以B为基数打印数字,请尝试
1 2 | (3735928559).toString(16); // to base 16:"deadbeef" parseInt("deadbeef", 16); // from base 16: 3735928559 |
参考页
JS数字格式快速教程
tofixed()的Mozilla引用页(带有指向topRection()、toExponential()、toLocaleString()的链接,…)
从上的ES6可以使用模板字符串:
1 2 3 | let soMany = 10; console.log(`This is ${soMany} times easier!`); //"This is 10 times easier! |
请注意,模板字符串由反勾号`而不是(单)引号包围。
更多信息:
https://developers.google.com/web/updates/2015/01/es6-template-strings
https://developer.mozilla.org/en-us/docs/web/javascript/reference/template_字符串
注:检查Mozilla站点以查找支持的浏览器列表。
芝宝JSXT
这个选项更适合。
1 2 3 4 5 6 7 8 | 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; }; |
使用此选项,我可以替换如下字符串:
1 | 'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP'); |
使用您的代码,第二个0将不会被替换。;)
我使用这个简单的函数:
1 2 3 4 5 6 7 | String.prototype.format = function() { var formatted = this; for( var arg in arguments ) { formatted = formatted.replace("{" + arg +"}", arguments[arg]); } return formatted; }; |
这与string.format非常相似:
1 | "{0} is dead, but {1} is alive!".format("ASP","ASP.NET") |
对于node.js用户,
1 | util.format("%s world","Hello") |
这里是一个用javascript实现sprintf的最小方法:它只做了"%s"和"%d",但我为它的扩展留出了空间。这对OP来说是没用的,但是其他从Google偶然发现这个线索的人可能会从中受益。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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; }); } |
例子:
1 2 | alert(sprintf('Latitude: %s, Longitude: %s, Count: %d', 41.847, -87.661, 'two')); // Expected output: Latitude: 41.847, Longitude: -87.661, Count: 0 |
与之前回复中的类似解决方案相比,这个解决方案一次完成所有替换,因此它不会替换先前替换的部分值。
我很惊讶没有人使用
1 2 3 4 5 | 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')); |
1 2 3 4 5 6 7 | 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" |
它是如何工作的:
reduce applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
1 2 3 4 5 6 7 8 9 | var _r= function(p,c){return p.replace(/%s/,c)}; console.log( ["a","b","c"].reduce(_r,"[%s], [%s] and [%s]") + ' ', [1, 2, 3].reduce(_r,"%s+%s=%s") + ' ', ["cool", 1337,"stuff"].reduce(_r,"%s %s %s") ); |
javascript程序员可以在https://github.com/ildar-shaimordanov/jsxt/blob/master/js/string.js上使用string.prototype.sprintf。下面是示例:
1 2 3 4 5 | var d = new Date(); var dateStr = '%02d:%02d:%02d'.sprintf( d.getHours(), d.getMinutes(), d.getSeconds()); |
+1 zippo,除非函数体需要如下所示,否则它会在每次迭代中附加当前字符串:
1 2 3 4 5 6 7 | String.prototype.format = function() { var formatted = this; for (var arg in arguments) { formatted = formatted.replace("{" + arg +"}", arguments[arg]); } return formatted; }; |
型
在
1 2 3 4 5 6 7 8 9 10 | 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. |
号
我还有一个非原型版本,我经常使用它的Java类语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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更新
ES 2015的所有新产品都让这变得更容易:
1 2 3 4 5 6 7 8 9 | 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." |
号
我想,因为这和以前的一样,实际上并没有解析字母,所以它可能只使用一个标记
1 2 | format("I love percentage signs! %%","%%"); //"I love percentage signs! %%" |
号
我将添加我自己的发现,这是我自问起发现的:
- 数字格式(千位分隔符/货币格式)
- sprintf(与上述作者相同)
遗憾的是,sprintf似乎没有处理像.NET字符串格式那样的千位分隔符格式。
型
非常优雅:
1 2 3 4 5 6 7 8 9 | 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}") |
。
信用卡转到(broken link)https://gist.github.com/0i0/1519811
我使用一个名为string.format for javascript的小库,它支持大多数格式字符串功能(包括数字和日期的格式),并使用.NET语法。脚本本身小于4KB,因此不会产生太多开销。
型
我想分享我的"问题"解决方案。我还没有重新发明轮子,但是我试图找到一个基于javascript的解决方案。优点是,您可以免费获得所有隐式转换。设置字符串的原型属性$提供了一个非常好和简洁的语法(参见下面的示例)。这可能不是最有效的方法,但在大多数情况下处理输出时,它不必进行超级优化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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)); } |
以下是几个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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' |
号
如果您希望处理千位分隔符,那么应该使用javascript number类中的toLocaleString(),因为它将格式化用户区域的字符串。
javascript日期类可以格式化本地化的日期和时间。
我有一个非常接近彼得的解决方案,但它涉及数字和对象案例。
1 2 3 4 5 6 7 8 9 10 11 12 | 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); }); }; } |
也许处理所有的深水案件会更好,但对于我的需要,这是很好的。
1 2 | "This is an example from {name}".format({name:"Blaine"}); "This is an example from {0}".format("Blaine"); |
PS:如果您在模板框架(如AngularJS)中使用翻译,则此函数非常酷:
1 2 | {{('hello-message'|translate).format(user)}} {{('hello-by-name'|translate).format( user ? user.name : 'You' )}} |
其中en.json类似于
1 2 3 4 | { "hello-message":"Hello {name}, welcome.", "hello-by-name":"Hello {0}, welcome." } |
phpjs项目已经为php的许多函数编写了javascript实现。由于php的
我用这个:
1 2 3 4 5 6 7 | String.prototype.format = function() { var newStr = this, i = 0; while (/%s/.test(newStr)) newStr = newStr.replace("%s", arguments[i++]) return newStr; } |
然后我称之为:
1 2 3 | "%s<p> %s </p>".format("Header","Just a test!"); |
型
有一个稍有不同的版本,我更喜欢这个版本(这个版本使用xxx标记,而不是0编号的参数,这更适合自我记录,更适合本地化):
1 2 3 4 5 6 7 | 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; }; |
一个变化是:
1 | var formatted = l(this); |
。
首先调用l()本地化函数。
在http://www.webtoolkit.info/javascript-sprintf.html上可以找到javascript的"sprintf"。
对于那些喜欢node.js及其
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 | 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(' ') > -1) { if (array) { str = str.split(' ').map(function (line) { return ' ' + line; }).join(' ').substr(2); } else { str = ' ' + str.split(' ').map(function (line) { return ' ' + line; }).join(' '); } } } 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 + ' ') + ' ' + output.join(', ') + ' ' + 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; }; |
摘自:https://github.com/joyent/node/blob/master/lib/util.js
为了防止有人需要一个功能来防止污染全球范围,以下是相同的功能:
1 2 3 4 5 | function _format (str, arr) { return str.replace(/{(\d+)}/g, function (match, number) { return typeof arr[number] != 'undefined' ? arr[number] : match; }); }; |
型
我这里有一个稍微长一点的javascript格式化程序…
您可以通过以下几种方式设置格式:
- 百万千克1江户十一〔七〕号百万千克1百万千克1埃多克斯1〔8〕百万千克1百万千克1江户十一〔九〕号百万千克1百万千克1埃多克斯1〔10〕百万千克1
型
另外,如果您说的是objectbase.prototype.format(例如与datejs一起使用),它将使用它。
示例…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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})" |
我还使用了.a s format作为别名,并在已经有了string.format的情况下进行了一些检测(例如使用MS Ajax工具包(我讨厌这个库)。
对于基本格式:
1 2 | var template = jQuery.validator.format("{0} is not a valid value"); var result = template("abc"); |
型
我没有看到
1 2 3 4 5 6 | String.format = function (string) { var args = Array.prototype.slice.call(arguments, 1, arguments.length); return string.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] !="undefined" ? args[number] : match; }); }; |
。
型
用于jquery.ajax()成功函数。只传递一个参数,字符串替换为该对象的属性propertyname:
1 2 3 4 5 6 7 8 | String.prototype.format = function () { var formatted = this; for (var prop in arguments[0]) { var regexp = new RegExp('\\{' + prop + '\\}', 'gi'); formatted = formatted.replace(regexp, arguments[0][prop]); } return formatted; }; |
号
例子:
1 | var userInfo = ("Email: {Email} - Phone: {Phone}").format({ Email:"[email protected]", Phone:"123-123-1234" }); |
号
型
有了sprintf.js,您可以将一个漂亮的小格式变薄。
1 2 3 4 5 6 7 8 | String.prototype.format = function(){ var _args = arguments Array.prototype.unshift.apply(_args,[this]) return sprintf.apply(undefined,_args) } // this gives you: "{%1$s}{%2$s}".format("1","0") // {1}{0} |
号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /** * Format string by replacing placeholders with value from element with * corresponsing index in `replacementArray`. * Replaces are made simultaneously, so that replacement values like * '{1}' will not mess up the function. * * Example 1: * ('{2} {1} {0}', ['three', 'two' ,'one']) -> 'one two three' * * Example 2: * ('{0}{1}', ['{1}', '{0}']) -> '{1}{0}' */ function stringFormat(formatString, replacementArray) { return formatString.replace( /\{(\d+)\}/g, // Matches placeholders, e.g. '{1}' function formatStringReplacer(match, placeholderIndex) { // Convert String to Number placeholderIndex = Number(placeholderIndex); // Make sure that index is within replacement array bounds if (placeholderIndex < 0 || placeholderIndex > replacementArray.length - 1 ) { return placeholderIndex; } // Replace placeholder with value from replacement array return replacementArray[placeholderIndex]; } ); } |
我在列表中没有看到pyformat,所以我想我会把它扔进去:
1 2 3 4 5 6 7 8 9 | 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'} )) |
jquery globalize项目中还有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * Qt stil arg() * var scr ="".arg("mydiv").arg("mydivClass"); */ String.prototype.arg = function() { var signIndex = this.indexOf("%"); var result = this; if (signIndex > -1 && arguments.length > 0) { var argNumber = this.charAt(signIndex + 1); var _arg ="%"+argNumber; var argCount = this.split(_arg); for (var itemIndex = 0; itemIndex < argCount.length; itemIndex++) { result = result.replace(_arg, arguments[0]); } } return result; } |
使用lodash,您可以获得模板功能:
使用ES模板文本分隔符作为"插入"分隔符。通过替换"interpolate"分隔符禁用支持。
1 2 3 | var compiled = _.template('hello ${ user }!'); compiled({ 'user': 'pebbles' }); // => 'hello pebbles! |
型
我需要一个函数,它可以按照用户喜欢的方式格式化价格(以美分表示),而复杂的部分是格式由用户指定——我不希望我的用户理解printf之类的语法或regexps等。我的解决方案与BASIC中使用的有点类似,因此用户只需用位来标记数字,例如:
1 2 3 4 | simple_format(1234567,"$ ###,###,###.##") "$ 12,345.67" simple_format(1234567,"### ### ###,## pln") "12 345,67 pln" |
号
我相信这很容易被用户理解,也很容易实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function simple_format(integer,format){ var text =""; for(var i=format.length;i--;){ if(format[i]=='#'){ text = (integer%10) + text; integer=Math.floor(integer/10); if(integer==0){ return format.substr(0,i).replace(/#(.*#)?/,"")+text; } }else{ text = format[i] + text; } } return text; } |
号
型
Bobjs可以做到:
1 2 3 4 5 6 | var sFormat ="My name is {0} and I am {1} years old."; var result = bob.string.formatString(sFormat,"Bob", 29); console.log(result); //output: //========== // My name is Bob and I am 29 years old. |
号
这并不是
使用此库的格式表达式采用嵌入的javascript对象的形式,例如
1 | format("I have {number: {currency:"$", precision:2}}.",50.2); |
将返回
我开始将
https://github.com/robau/javascript.string.format.
您可以简单地添加javscript并调用
请注意,尚未完成,但欢迎反馈:)
型
你可以使用这个功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | String.prototype.format = function (args) { var str = this; return str.replace(String.prototype.format.regex, function(item) { var intVal = parseInt(item.substring(1, item.length - 1)); var replace; if (intVal >= 0) { replace = args[intVal]; } else if (intVal === -1) { replace ="{"; } else if (intVal === -2) { replace ="}"; } else { replace =""; } return replace; }); }; String.prototype.format.regex = new RegExp("{-?[0-9]+}","g"); // Sample usage. var str ="She {1} {0}{2} by the {0}{3}. {-1}^_^{-2}"; str = str.format(["sea","sells","shells","shore"]); alert(str); |
号
型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | String.prototype.repeat = function(n) { return new Array(++n).join(this); }; String.prototype.pad = function(requiredLength, paddingStr, paddingType) { var n = requiredLength - this.length; if (n) { paddingType = paddingType ? paddingType.toLowerCase() : ''; paddingStr = paddingStr || ' '; paddingStr = paddingStr.repeat( Math.ceil(n / paddingStr.length) ).substr(0, n); if (paddingType == 'both') { n /= 2; return paddingStr.substr( 0, Math.ceil(n) ) + this + paddingStr.substr( 0, Math.floor(n) ); } if (paddingType == 'left') { return paddingStr + this; } return this + paddingStr; } return this; }; // синтаксис аналогичен printf // 'Привет, %s!'.format('мир') ->"Привет, мир!" // '%.1s.%.1s. %s'.format('Иван', 'Иванович', 'Иванов') ->"И.И. Иванов" String.prototype.format = function() { var i = 0, params = arguments; return this.replace(/%(?:%|(?:(|[+-]+)(|0|'.+?)([1-9]\d*)?(?:\.([1-9]\d*))?)?(s|d|f))/g, function(match, sign, padding, width, precision, type) { if (match == '%%') { return '%'; } var v = params[i++]; if (type == 'd') { v = Math.round(v); } else if (type == 'f') { v = v.toFixed(precision ? precision : 6); } if (/\+/.test(sign) && v > 0) { v = '+' + v; } v += ''; if (type != 'f' && precision) { v = v.substr(0, precision); } if (width) { v = v.pad(width, padding == '' ? ' ' : padding[0] =="'" ? padding.substr(1) : padding, /-/.test(sign) ? 'right' : 'left'); } return v; }); }; // this.name = 'Вася'; // console.log( 'Привет, ${name}!'.template(this) ); //"Привет, Вася!" String.prototype.template = function(context) { return this.replace(/\$\{(.*?)\}/g, function(match, name) { return context[name]; }); }; |
型
这一个与0、1和一起工作。
1 2 3 4 5 6 7 | String.prototype.format = function format() { var msg = this; for(var i in arguments) msg = msg.replace(/\{\}/,arguments[i]).replace(new RegExp('\\{'+i+'\\}','g'),arguments[i]); return msg; } |
。
型
这是coffeescript的https://stackoverflow.com/a/4673436/1258486的实现。
https://gist.github.com/eces/5669361
1 2 3 4 5 | if String.prototype.format is undefined String.prototype.format = () -> _arguments = arguments this.replace /{(\d+)}/g, (match, number) -> if typeof _arguments[number] isnt 'undefined' then _arguments[number] else match |
。