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

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

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


当前回答

我有一个非常接近Peter的解决方案,但它涉及数字和对象情况。

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

也许处理所有深度案件会更好,但对于我的需要来说,这很好。

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

PS:如果你在AngularJS这样的模板框架中使用翻译,这个函数非常酷:

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

en.json是什么样子的

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

其他回答

从上的ES6可以使用模板字符串:

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_strings

注:查看mozilla站点以查找支持的浏览器列表。

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

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

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

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

将返回“我有50.20美元”。

JavaScript有“sprintf”,您可以在http://www.webtoolkit.info/javascript-sprintf.html.

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

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