我正在寻找一个与C/PHP printf()或C#/Java程序员String.Format()(IFormatProvider for.NET)相当的JavaScript。

目前,我的基本要求是数字的千位分隔符格式,但处理大量组合(包括日期)的格式会很好。

我意识到Microsoft的Ajax库提供了String.Format()的一个版本,但我们不希望该框架的全部开销。


当前回答

现在,有一个名为locatus的包,它将其他语言的函数转换为Javascript,如php、python、ruby等。

const printf = require('locutus/php/strings/printf')
printf('Hello world');

你可以试试这个游乐场代码沙盒

其他回答

有了sprintf.js,你可以制作一个漂亮的小格式

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}

我需要一个函数,它可以以用户喜欢的方式格式化价格(以美分为单位),而棘手的是,格式是由用户指定的——我不希望我的用户理解类似printf的语法或regexp等。我的解决方案与Basic中使用的解决方案有些相似,因此用户只需使用数字的#位置进行标记,例如:

simple_format(1234567,"$ ###,###,###.##")
"$ 12,345.67"
simple_format(1234567,"### ### ###,## pln")
"12 345,67 pln"

我相信这很容易被用户理解,也很容易实现:

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

基于先前建议的解决方案:

// 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}已死亡,但{1}仍活着!{0{{2}”.format(“ASP”,“ASP.NET”)

输出

ASP死了,但ASP.NET活了!ASP{2}


如果您不想修改String的原型:

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

让您更加熟悉:

String.format(“{0}无效,但{1}有效!{0{{2}”,“ASP”,“ASP.NET”);

结果相同:

ASP死了,但ASP.NET活了!ASP{2}

这不是sprintf的精确复制;然而,它是类似的,并且更强大:https://github.com/anywhichway/stringformatter

使用此库的格式表达式采用嵌入式Javascript对象的形式,例如。

format("I have {number: {currency: "$", precision:2}}.",50.2); 

将返回“我有50.20美元”。

我想分享我对“问题”的解决方案。我没有重新发明轮子,但试图根据JavaScript已经做的事情找到解决方案。优点是,您可以免费获得所有隐式转换。设置字符串的原型属性$提供了一个非常好和紧凑的语法(参见下面的示例)。这可能不是最有效的方法,但在大多数情况下,处理输出时不必进行超级优化。

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

以下是几个示例:

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'