JavaScript对应于printf/String.Format的函数

2411

我正在寻找一个良好的JavaScript等价物来替代C/PHP中的printf()或对于C#/Java程序员,String.Format()(.NET使用 IFormatProvider)。

我的基本要求是数字的千位分隔符格式,但能处理许多组合(包括日期)的东西会更好。

我意识到微软的Ajax库提供了一个版本的String.Format(),但我们不想要整个框架的开销。


4
除了下面众多优秀的回答,您或许也想看看这个链接:https://dev59.com/pXNA5IYBdhLWcg3wPbSe#2648463,在我看来,这是解决此问题最高效的方法。 - Annie
3
我写了一个简单的程序,使用类C语言的printf语法。 - Braden Best
var search = [$scope.dog, "1"]; var url = vsprintf("http://earth/Services/dogSearch.svc/FindMe/%s/%s", search); ***对于Node,您可以通过“npm install sprintf-js”获取您的模块。 - Jenna Leaf
5
这里的大多数答案都令人失望。printf和String.Format不仅仅是简单的模板,而且问题特别提到了千位分隔符,这是简单模板解决方案都无法处理的。 - blm
除了“模板字符串”之外,人们可能还在寻找String.padStart。 (请参见https://dev59.com/jXE85IYBdhLWcg3wnU-p) - Nor.Z
显示剩余3条评论
61个回答

0

如果你需要一个printf,请使用printf

看起来90%的评论者从未使用过比仅使用%d更复杂的格式的printf。我想知道他们如何输出例如货币值?


字符串外的格式化。JavaScript 中存在 (213.3244).toFixed(2),其他语言有其他方法(C# 有 Decimal.Truncate(),或者使用 Math.Round()/Math.round())。许多语言中也包含文化信息。C# 中的 System.Globalization 就是一个例子,JavaScript 中的 (324).toLocaleString() 也是如此。这个答案只适用于 Node.js,而不适用于浏览器。考虑到问题没有指定是浏览器还是 node,这个答案对于该情况可能被认为是无用的(但对于其他人来说是有帮助的)。在这里,模板字符串是最好的解决方案。 - Lilly

0

现在有一个名为locutus的包,它可以将其他语言的函数转换为JavaScript,例如php、python、ruby等。

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

你可以尝试这个 codesandbox 游乐场。

我发现了一个错误并提供了修复。现在应该可以完美地工作了。谢谢你的提醒! - Param Siddharth

0

bobjs 可以做到这一点:

var sFormat = "My name is {0} and I am {1} years old."; 
var result = bob.string.formatString(sFormat, "Bob", 29); 
console.log(result); 
//output: 
//========== 
// My name is Bob and I am 29 years old. 

0
我回答这个问题是基于以下几个原因:
- `sprintf`/`printf` 允许你提供可变长度的参数。 - 前面的答案使用了模板字面量。当使用模板字面量时,你必须知道你有多少个参数。
从我的角度来看,@Braden Best 和 @David Spector 的答案似乎是有效的。
我添加了以下答案,以便有人可以在一个地方找到答案。
解释如下:
- 在该方法中,你将你想要的模板字符串作为第一个参数传递进去,并且使用占位符 `:param`。此外,你可以传递任意多个替换值。 - 然后它遍历传递的值,并用当前迭代的值替换下一个 `:param`。
主要的是,如果你知道 `Array.reduce` 和 `String.replace` 的作用,你就能理解这段代码。
你可以将 `:param` 更改为任何你想要的内容。同时,在这种情况下,你需要在 `sprintf` 方法中更改 `:param`。

function sprintf(format, ...values) {
  return values.reduce((carry, current) => carry.replace(/:param/, current), format);
}

console.log(sprintf('Hello :param! How are you :param. Are you over :param?', 'World', 'Anik', 18));
console.log(sprintf('Nothing to be replaced in here!'));
console.log(sprintf('https://httpbin.org/users/:param/posts/:param', 'anik', 'abcdefgh'));
console.log(sprintf('hello :param! How are you :param. Are you over :param? ":param"', 'world', 'anik', 18, ['extra', 'params']));
console.log(sprintf('hello :param'));
console.log(sprintf('hello', 1,2,3,4));


0
export function stringFormat (str: string, ...args: string[]) {
     return args.reduce((acc, curr, i) => acc.replace(new RegExp("\\{" + i + "\\}", 'g'), curr), str);
}

0

如果你只需要使用 %s 格式说明符 格式化一个字符串

function _sprintf(message){
    const regexp = RegExp('%s','g');
    let match;
    let index = 1;
    while((match = regexp.exec(message)) !== null) {
        let replacement = arguments[index];
        if (replacement) {
            let messageToArray = message.split('');
            messageToArray.splice(match.index, regexp.lastIndex - match.index, replacement);
            message = messageToArray.join('');
            index++;
        } else {
            break;
        }
    }

    return message;
}

_sprintf("my name is %s, my age is %s", "bob", 50); // my name is bob, my age is 50

0
在 TypeScript 中创建一个名为 format.ts 的文件,并在需要使用格式化的地方导入它。
// contents of format.ts

interface String {
  format(...args: any[]): string;
}

if (!String.prototype.format) {
  String.prototype.format = function() {
    let a = this;
    let b: any;
    // tslint:disable-next-line: forin
    for (b in arguments) {
      a = a.replace(/%[a-z]/, arguments[b]);
    }
    return a;
  };
}

使用以下代码格式化字符串:

import './format';

console.log('Hello, %s!'.format('World'));

例子

String.prototype.format = function() {
  let a = this;
  let b;
  for (b in arguments) {
    a = a.replace(/%[a-z]/, arguments[b]);
  }
  return a;
};

console.log('Hello, %s!'.format('World'));


-1

这不是sprintf的精确副本;但是它更加相似且更有力量:https://github.com/anywhichway/stringformatter

使用此库格式化表达式采用内嵌的 Javascript 对象形式,例如:

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

将返回"我有$50.20。"


-1

这不是世界上最推荐的函数,但它可以工作。

如果你需要 sprintf,只需复制并粘贴此相同的函数,并将 return console.log(sb) 更改为 return sb

printf = function(s, /*args...*/) {
    a = arguments;
    al = a.length;
    
    if (al <= 1) return -2;
    if (al >= 2 && s.toLowerCase().search(/%[a-z]/) == -1) return -1;

    sb = s;
    for (i = 1; i <= al - 1; i++) {
        sb = sb.replace(/%[a-z]/, a[i]);
    }

    return console.log(sb);
}

var someString = "Hello %s\nIt's %s:%s %s now.\nThe day is %s\n";
printf(someString, "StackOverflowUser", "5", "48", "PM", "beautiful");


-1

只需使用模板字符串和箭头函数即可。这甚至使它们具有可重复使用性。

const greeter = (name, birthplace) => `Hi, I'm ${name}, I'm from ${birthplace}!`;


console.log( greeter('Sean', 'Earth') )

如果您使用...spread运算符,您可以使用定位参数:

const greeterPosition = (...a) => `Hi, I'm ${a[0]}, I'm from ${a[1]}!`;

console.log( greeterPosition('Sean', 'Earth') );

如果您喜欢,甚至可以组合它们:

const greeterA = (name) => `Hi, I'm ${name}`;
const greeterB = (birthplace) => `I'm from ${birthplace}`;

const greeterComposed = (...a) => greeterA(a[0]) + ', ' + greeterB(a[1]) + '!';

console.log( greeterComposed('Sean', 'Earth') );

如果你真的需要类型限制:

// alias the types for conciseness' sake
const [b,n,s,h] = [Boolean,Number,String,d=>Number(d).toString(16)];

const onlyBools   = (...a) => `onlyBools:\nThese were Bools ${b(a[0])} ${b(a[1])}.\nThese were strings: ${b(a[2])}, ${b(a[3])}.\n...And this was a number: ${b(a[4])}`;
const onlyNumbers = (...a) => `onlyNumbers:\nThese were Bools ${n(a[0])} ${n(a[1])}.\nThese were strings: ${n(a[2])}, ${n(a[3])}.\n...And this was a number: ${n(a[4])}`;
const onlyHex     = (...a) => `onlyHex:\nThese were Bools ${h(a[0])} ${h(a[1])}.\nThese were strings: ${h(a[2])}, ${h(a[3])}.\n...And this was a number: ${h(a[4])}`;
const onlyStrings = (...a) => `onlyStrings:\nThese were Bools ${s(a[0])} ${s(a[1])}.\nThese were strings: ${s(a[2])}, ${s(a[3])}.\n...And this was a number: ${s(a[4])}`;


console.log( onlyBools(true, false, 'not boolean', '', 77) );
console.log( onlyNumbers(true, false, 'not boolean', '', 77) );
console.log( onlyHex(true, false, 'not boolean', '', 77) );
console.log( onlyStrings(true, false, 'not boolean', '', 77) );


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接