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

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

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


当前回答

JavaScript程序员可以在https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js.以下是示例:

var d = new Date();
var dateStr = '%02d:%02d:%02d'.sprintf(
    d.getHours(), 
    d.getMinutes(), 
    d.getSeconds());

其他回答

除了zippoxer的答案,我还使用了这个函数:

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的语法:

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中所有酷炫的新功能让这一切变得更加简单:

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."

我想,因为这和以前的一样,实际上并不能解析字母,所以最好只使用一个标记%%。这样做的好处是显而易见的,并且不会使使用单一的%变得困难。但是,如果出于某种原因需要%%,则需要将其替换为自身:

format("I love percentage signs! %%", "%%");
// "I love percentage signs! %%"

3种不同的javascript字符串格式

有三种不同的方法通过用变量值替换占位符来格式化字符串。

使用模板文本(反引号``)let name=“John”;假设年龄=30;//使用倒钩console.log(`${name}是${age}岁。`);//约翰30岁了。使用串联

let name=“John”;假设年龄=30;//使用串联console.log(name+'是'+age+'岁');//约翰30岁了。

创建自己的格式函数

String.prototype.format=函数(){var args=参数;返回this。replace(/{([0-9]+)}/g,函数(匹配,索引){//检查参数是否存在返回参数类型[index]==“undefined”?匹配:args[index];});};console.log(“{0}是{1}年前的。”.format(“John”,30));

使用Lodash,您可以获得模板功能:

使用ES模板文本分隔符作为“插入”分隔符。通过替换“interpole”分隔符禁用支持。

var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!
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];
    });
};

JavaScript中的sprintf()函数模拟为Vue过滤器和String.protype.format()扩展:

/**
 * Returns a formatted string.
 *
 * @param template
 * @param values
 * @return string
 */
String.format = function (template, ...values) {
    let i = -1;

    function callback(exp, p0, p1, p2, p3, p4) {
        if (exp === '%%') return '%';
        if (values[++i] === undefined) return undefined;

        exp = p2 ? parseInt(p2.substr(1)) : undefined;

        let base = p3 ? parseInt(p3.substr(1)) : undefined;
        let val;

        switch (p4) {
            case 's': val = values[i]; break;
            case 'c': val = values[i][0]; break;
            case 'f': val = parseFloat(values[i]).toFixed(exp); break;
            case 'p': val = parseFloat(values[i]).toPrecision(exp); break;
            case 'e': val = parseFloat(values[i]).toExponential(exp); break;
            case 'x': val = parseInt(values[i]).toString(base ? base : 16); break;
            case 'd': val = parseFloat(parseInt(values[i], base ? base : 10).toPrecision(exp)).toFixed(0); break;
        }
        val = typeof (val) == 'object' ? JSON.stringify(val) : val.toString(base);
        let sz = parseInt(p1); /* padding size */
        let ch = p1 && p1[0] === '0' ? '0' : ' '; /* isnull? */

        while (val.length < sz) val = p0 !== undefined ? val + ch : ch + val; /* isminus? */

        return val;
    }

    let regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;

    return template.replace(regex, callback);
}

String.prototype.format = function() {
    return String.format(this, ...arguments);
}

const StringFormat = {
    install: (Vue, options) => {
        Vue.filter('format', function () {
            return String.format(...arguments);
        });
    },
};

export default StringFormat;

原始答案:JavaScript相当于printf/String.Format