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

问题描述 投票:0回答:20

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 实现相同的语法?

javascript format string-interpolation
20个回答
69
投票

另一种方法,使用

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"

64
投票

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

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

jsfiddle - 链接


35
投票

tl;博士

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

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

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

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)

解决方案

通过箭头函数,我们可以优雅地包装模板字符串以供以后使用:

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

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

foo(bar3, bar2, bar1)

当然,这也适用于常规函数,但箭头函数允许我们将其设为单行函数。这两个功能在大多数浏览器和运行时都可用:


12
投票

在寻找同一问题的答案时,我刚刚找到了这个:https://github.com/davidchambers/string-format,这是“受Python启发的JavaScript字符串格式化

str.format()
”。看起来和python的
format()
函数几乎一样。


7
投票

取自雅虎图书馆:

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

6
投票

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

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

我认为这很有帮助。


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
调用,使其更加高效。

编辑:更改它,以便在不传递任何参数的情况下引发相同的错误。


2
投票

于山岛分裂:

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


1
投票

此代码允许您准确指定用哪些字符串替换哪些括号。括号不需要与参数的顺序相同,并且可以有多个括号。格式函数采用一个值数组作为其参数,每个键都是括号中的“变量”之一,由其相应的值替换。

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

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

输出:

Python 的 format() 函数的 JavaScript 等价物:

懒狗跳过了foobar

演示:

jsFiddle


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

1
投票

实现简单,无需使用额外功能

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

1
投票
String.prototype.format = function(args){
  //args - hash of params
  var text = this
  for(var attr in args){
    text = text.split('${' + attr + '}').join(args[attr]);
  }
  return text
}

用法:'你好,${NAME}。这是 ${FORMAT}'.format({NAME:'guys',FORMAT:'format()'})

更新:Python 的 f 结尾字符串:

Python: f'string {expr}'
JavaScript: `string ${expr}`

0
投票

JavaScript 没有这样的函数 AFAIK。

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

在 format 方法中,您必须获取字符串的实例值(实际字符串),然后解析它以查找“{}”并插入适当的参数。

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


0
投票

JavaScript 默认情况下没有字符串格式化函数,尽管您可以创建自己的或使用其他人制作的字符串格式化函数(例如 sprintf


0
投票

在文件中

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

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


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)


0
投票

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

Javascript 调用:

format(str, data)

类似的 python 调用:

str.format(**data)
,但需要注意的是,与 Python 不同,如果字符串包含在提供的数据中找不到的 varname,则此 javascript 函数不会抛出错误。

/*
 * format(str, data): analogous to Python's str.format(**data)
 *
 * Example:
 *   let data = {
 *     user: {
 *       name: { first: 'Jane', last: 'Doe' }
 *     },
 *     email: '[email protected]',
 *     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 [email protected], 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;
}

0
投票

PatrikAkerstrand 报道的YAHOO

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


0
投票

该方法支持基于索引和基于位置的插入

链接到源代码

const formatStr = (str: string, ...args: (string | number | boolean)[]) => {
  let i = -1;
  return str.replace(/{\d}|{}/g, (match) => {
    i += 1;
    if (match === "{}") {
        return typeof args[i] !== "undefined" ? String(args[i]) : "";
    }
    const idx = parseInt(match.replace(/{|}/g, ""));
    return typeof args[idx] !== "undefined" ? String(args[idx]) : "";
  });
};

...

formatStr("hello {1} world {0} foo {}", 1,2,3) // hello 2 world 1 foo 3

© www.soinside.com 2019 - 2024. All rights reserved.