标题: JavaScript里的sprintf函数
作者: Demon
链接: https://demon.tw/programming/javascript-sprintf.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
最近老在搞和115网盘有关的东西,博客流量很大一部分都是和115有关的关键词带来的。但是我的标签小程序被封杀之后,我就懒得研究了。反正我又不用115网盘,爱封不封,对我没有丝毫影响。
今天稍稍看了一下uTorrent Apps SDK,想研究一下把uRatio嵌入uTorrent中的可能性。跟着文档中的Tutorials一步一步学习,最先学习的是Content Catalog,前面主要讲怎么配置开发环境和新建一个uTorrent App工程。看了半天,终于看到出现代码了:
$(document).ready(function() { var JSONP_URL = 'http://vodo.net/jsonp/releases/all?callback=?'; var loading = $('<p>Loading\u2026</p>').appendTo('body'); $.getJSON(JSONP_URL, function(items) { _.each(items, function(value, key) { var elem = $(sprintf('<li id="%s">', value.title.replace(/\W+/g, '_'))); elem.appendTo('#items'); new bt.Widget.Download({ name : value.title, url : value.torrents[0].url, elem : $(elem).empty()[0], buttons : { download : ['Get %s', 'Loading\u2026'], play : ['Play %s', 'Replay %s'] } }); }); loading.remove(); }); });
突然眼前一亮,神马?sprintf!学过C的人总是对printf()系列函数难以忘怀,他们在学新的语言时总不免感概:是的!是printf(),它们忘了把printf()放进去了。在JavaScript中看到sprintf,有种熟悉的感觉。于是把sprintf函数的实现找了出来:
function str_repeat(i, m) { for (var o = []; m > 0; o[--m] = i); return o.join(''); } function sprintf() { var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = ''; while (f) { if (m = /^[^\x25]+/.exec(f)) { o.push(m[0]); } else if (m = /^\x25{2}/.exec(f)) { o.push('%'); } else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) { if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) { throw('Too few arguments.'); } if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) { throw('Expecting number but found ' + typeof(a)); } switch (m[7]) { case 'b': a = a.toString(2); break; case 'c': a = String.fromCharCode(a); break; case 'd': a = parseInt(a); break; case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break; case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break; case 'o': a = a.toString(8); break; case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break; case 'u': a = Math.abs(a); break; case 'x': a = a.toString(16); break; case 'X': a = a.toString(16).toUpperCase(); break; } a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a); c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' '; x = m[5] - String(a).length - s.length; p = m[5] ? str_repeat(c, x) : ''; o.push(s + (m[4] ? a + p : p + a)); } else { throw('Huh ?!'); } f = f.substring(m[0].length); } return o.join(''); }
其实,早就有人把sprintf函数写成了jQuery插件,除了实现C中sprintf的功能外,还实现了类似Python的命名参数功能:
赞赏//sprintf //positional arguments var classic = $.sprintf('%s %d%% %.3f', 'string', 40, 3.141593); // classic = 'string 40% 3.142' //named arguments var named = $.sprintf('%(name)s: %(value)d', {name: 'age', value: 40}); // named = 'age: 40' //vsprintf var classic = $.vsprintf('%s %d%% %.3f', ['string', 40, 3.141593]); // classic = 'string 40% 3.142' //named arguments var named = $.vsprintf('%(name)s: %(value)d', [{name: 'age', value: 40}]); // named = 'age: 40'
微信赞赏支付宝赞赏
随机文章:
这个有点儿意思,在很多时候还是蛮实用的