JavaScript相当于Python的format()函数?

时间:2011-02-11 21:26:39

标签: javascript python format

Python有这个很棒的功能来解决这个问题:

bar1 = 'foobar'
bar2 = 'jumped'
bar3 = 'dog'

foo = 'The lazy ' + bar3 + ' ' + bar2 ' over the ' + bar1
# The lazy dog jumped over the foobar

进入这个:

bar1 = 'foobar'
bar2 = 'jumped'
bar3 = 'dog'

foo = 'The lazy {} {} over the {}'.format(bar3, bar2, bar1)
# The lazy dog jumped over the foobar

JavaScript有这样的功能吗?如果没有,我将如何创建一个遵循与Python实现相同的语法?

18 个答案:

答案 0 :(得分:42)

另一种方法,使用String.prototype.replace方法,将“replacer”函数作为第二个参数:

String.prototype.format = function () {
  var i = 0, args = arguments;
  return this.replace(/{}/g, function () {
    return typeof args[i] != 'undefined' ? args[i++] : '';
  });
};

var bar1 = 'foobar',
    bar2 = 'jumped',
    bar3 = 'dog';

'The lazy {} {} over the {}'.format(bar3, bar2, bar1);
// "The lazy dog jumped over the foobar"

答案 1 :(得分:19)

有一种方法,但不完全使用格式。

 
    var name = "John";
    var age = 19;
    var message = `My name is ${name} and I am ${age} years old`;
    console.log(message);

jsfiddle - link

答案 2 :(得分:10)

寻找同一问题的答案,我刚刚发现:https://github.com/davidchambers/string-format,这是“受Python str.format()启发的JavaScript字符串格式”。它似乎与python的format()函数几乎相同。

答案 3 :(得分:5)

取自YAHOOs图书馆:

YAHOO.Tools.printf = function() { 
  var num = arguments.length; 
  var oStr = arguments[0];   
  for (var i = 1; i < num; i++) { 
    var pattern = "\\{" + (i-1) + "\\}"; 
    var re = new RegExp(pattern, "g"); 
    oStr = oStr.replace(re, arguments[i]); 
  } 
  return oStr; 
} 

称之为:

bar1 = 'foobar'
bar2 = 'jumped'
bar3 = 'dog'

foo = YAHOO.Tools.printf('The lazy {0} {1} over the {2}', bar3, bar2, bar1); 

答案 4 :(得分:4)

这是我的第一次尝试。随意指出缺陷。

示例: http://jsfiddle.net/wFb2p/5/

String.prototype.format = function() {
    var str = this;
    var i = 0;
    var len = arguments.length;
    var matches = str.match(/{}/g);
    if( !matches || matches.length !== len ) {
        throw "wrong number of arguments";
    }
    while( i < len ) {
        str = str.replace(/{}/, arguments[i] );
        i++;
    }
    return str;
};

编辑:取消.match()声明中的while调用,提高效率。

编辑:更改了它,以便在您不传递任何参数时抛出相同的错误。

答案 5 :(得分:4)

tl; dr

foo = (a, b, c) => `The lazy ${a} ${b} over the ${c}`

为什么仅模板字符串还不够

ES6 template strings提供的功能与pythons字符串格式非常相似。但是,在构造字符串之前,必须先了解变量:

var templateString = `The lazy ${bar3} ${bar2} over the ${bar1}`;

为什么使用格式?

Python的str.format允许您指定字符串 before ,甚至可以知道要插入哪些值,例如:

foo = 'The lazy {} {} over the {}'

bar1 = 'foobar'
bar2 = 'jumped'
bar3 = 'dog'

foo.format(bar3, bar2, bar1)

解决方案

使用arrow function,我们可以优雅地包装模板字符串以备后用:

foo = (a, b, c) => `The lazy ${a} ${b} over the ${c}`

bar1 = 'foobar';
bar2 = 'jumped';
bar3 = 'dog';

foo(bar3, bar2, bar1)

当然,这也可以和常规函数一起使用,但是使用箭头功能可以使它成为单线。两种功能在大多数浏览器和运行时中都可用:

答案 6 :(得分:2)

Usando拆分:

String.prototype.format = function (args) {
    var text = this
    for(var attr in args){
        text = text.split('${' + attr + '}').join(args[attr]);
    }
    return text
};

json = {'who':'Gendry', 'what':'will sit', 'where':'in the Iron Throne'}
text = 'GOT: ${who} ${what} ${where}';

console.log('context: ',json);
console.log('template: ',text);
console.log('formated: ',text.format(json));

Usando正则表达式:

String.prototype.format = function (args) {
    var text = this
    for(var attr in args){
        var rgx = new RegExp('${' + attr + '}','g');
        text = text.replace(rgx, args[attr]);
    }
    return text
};

json = {'who':'Gendry', 'what':'will sit', 'where':'in the Iron Throne'}
text = 'GOT: ${who} ${what} ${where}';

console.log('context: ',json);
console.log('template: ',text);
console.log('formated: ',text.format(json));

答案 7 :(得分:1)

此代码允许您准确指定要用哪些字符串替换哪些括号。括号不需要与参数的顺序相同,并且多个括号是可能的。 format函数将一个值数组作为参数,每个键都是括号中的变量之一&#39;由相应的值代替。

String.prototype.format = function (arguments) {
    var this_string = '';
    for (var char_pos = 0; char_pos < this.length; char_pos++) {
        this_string = this_string + this[char_pos];
    }

    for (var key in arguments) {
        var string_key = '{' + key + '}'
        this_string = this_string.replace(new RegExp(string_key, 'g'), arguments[key]);
    }
    return this_string;
};

'The time is {time} and today is {day}, {day}, {day}. Oh, and did I mention that the time is {time}.'.format({day:'Monday',time:'2:13'});
//'The time is 2:13 and today is Monday, Monday, Monday. Oh, and did I mention that the time is 2:13.'

答案 8 :(得分:1)

JS:

String.prototype.format = function () {
    var str = this;
    for (var i = 0; i < arguments.length; i++) {
        str = str.replace('{' + i + '}', arguments[i]);
    }
    return str;
}

bar1 = 'foobar';
bar2 = 'jumped';
bar3 = 'dog';

python_format = 'The lazy {2} {1} over the {0}'.format(bar1,bar2,bar3);

document.getElementById("demo").innerHTML = "JavaScript equivalent of Python's format() function:<br><span id='python_str'>" + python_format + "</span>";

HTML:

<p id="demo"></p>

CSS:

span#python_str {
    color: red;
    font-style: italic;
}

输出:

  

JavaScript相当于Python的format()函数:

     

懒狗跳过foobar

样本:

jsFiddle

答案 9 :(得分:1)

String.prototype.format = function () {
    var i=0,args=arguments,formats={
        "f":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0'),f=parseInt(f||'-1');v=f>0?Math.floor(v).toString()+"."+Math.ceil(v*Math.pow(10,f)).toString().slice(-f):(f==-1?v.toString():Math.floor(v).toString());return c>v.length?s.repeat(c-v.length)+v:v;},
        "d":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0');v=Math.floor(v).toString();return c>v.length?s.repeat(c-v.length)+v:v;},
        "s":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0');return c>v.length?s.repeat(c-v.length)+v:v;},
        "x":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0');v=Math.floor(v).toString(16);return c>v.length?s.repeat(c-v.length)+v:v;},
        "X":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0');v=Math.floor(v).toString(16).toUpperCase();return c>v.length?s.repeat(c-v.length)+v:v;},
    };
    return this.replace(/{(\d+)?:?([0=-_*])?(\d+)?\.?(\d+)?([dfsxX])}/g, function () {
        let pos = arguments[1]||i;i++;
        return typeof args[pos] != 'undefined' ? formats[arguments[5]](args[pos],arguments[2],arguments[3],arguments[4]) : '';
    });
};

答案 10 :(得分:0)

简单实现,无需额外功能

[bar1, bar2, bar3].reduce(
  (str, val) => str.replace(/{}/, val),
  'The lazy {} {} over the {}'
)

答案 11 :(得分:0)

PatrikAkerstrand报告的我自己的YAHOO's printf简写版本:

function format() { 
  return [...arguments].reduce((acc, arg, idx) => 
    acc.replace(new RegExp("\\{" + (idx - 1) + "\\}", "g"), arg));
}

console.log(
  format('Confirm {1} want {0} beers', 3, 'you')
);

答案 12 :(得分:0)

如果您(像我一样)只需要python格式函数的有限子集来进行简单的字符串替换,并且性能并不重要,那么非常简单的29行纯Javascript函数就足够了。

JavaScript调用:format(str, data)

类似的python调用:str.format(**data),但要注意的是,与字符串不同的是,如果字符串包含在提供的数据中找不到的varname,则此javascript函数不会引发错误。

/*
 * format(str, data): analogous to Python's str.format(**data)
 *
 * Example:
 *   let data = {
 *     user: {
 *       name: { first: 'Jane', last: 'Doe' }
 *     },
 *     email: 'jane@doe.com',
 *     groups: ["one","two"]
 *   };
 *
 *   let str = 'Hi {user.name.first} {user.name.last}, your email address is {email}, and your second group is {groups[1]}'
 * 
 *   format(str, data)
 *   => returns "Hi Jane Doe, your email address is jane@doe.com, and your second group is two"
 */

function format(str, data) {
    var varnames = {};
    function array_path(path, i) {
        var this_k = '[' + i + ']';
        if (!path.length)
            return [this_k];
        path = path.slice();
        path[path.length - 1] += this_k;
        return path;
    }
    function add_varnames(this_data, path) {
        if (this_data.constructor == Array) {
            for (var i = 0; i < this_data.length; i++)
                add_varnames(this_data[i], array_path(path, i));
        }
        else if (this_data.constructor == Object) {
            for (var k in this_data)
                add_varnames(this_data[k], path.concat(k));
        }
        else {
            var varname = '{' + path.join('.') + '}';
            varnames[varname] = String(this_data);
        }
    }
    add_varnames(data, []);
    for (var varname in varnames)
        str = str.replace(varname, varnames[varname]);
    return str;
}

答案 13 :(得分:0)

您可以在JS中使用模板文字,

const bar1 = 'foobar'
const bar2 = 'jumped'
const bar3 = 'dog'
foo = `The lazy ${bar3} ${bar2} over the ${bar1}`

我认为这很有帮助。

答案 14 :(得分:0)

适合那些正在寻找简单ES6解决方案的人。

首先,我提供一个函数而不是扩展本机String原型,因为通常不鼓励这样做。

// format function using replace() and recursion

const format = (str, arr) => arr.length > 1 
	? format(str.replace('{}', arr[0]), arr.slice(1)) 
	: (arr[0] && str.replace('{}', arr[0])) || str

// Example usage

const str1 = 'The {} brown {} jumps over the {} dog'

const formattedString = formatFn(str1, ['quick','fox','lazy'])

console.log(formattedString)

答案 15 :(得分:0)

在文件

https://github.com/BruceSherwood/glowscript/blob/master/lib/glow/api_misc.js

是一个完全实现Python string.format()函数的函数String.prototype.format = function(args),不仅仅局限于处理字符串。

答案 16 :(得分:0)

默认情况下,JavaScript没有字符串格式化功能,但您可以自己创建或使用其他人创建的功能(例如sprintf

答案 17 :(得分:0)

JavaScript没有AFAIK这样的功能。

您可以通过修改String类的原型对象来创建一个,以添加一个带有可变数量参数的format()方法。

在format方法中,您必须获取String的实例值(实际字符串),然后将其解析为“{}”并插入相应的参数。

然后将新字符串返回给调用者。