我正在寻找一个良好的JavaScript等价物来替代C/PHP中的printf()
或对于C#/Java程序员,String.Format()
(.NET使用 IFormatProvider
)。
我的基本要求是数字的千位分隔符格式,但能处理许多组合(包括日期)的东西会更好。
我意识到微软的Ajax库提供了一个版本的String.Format()
,但我们不想要整个框架的开销。
我正在寻找一个良好的JavaScript等价物来替代C/PHP中的printf()
或对于C#/Java程序员,String.Format()
(.NET使用 IFormatProvider
)。
我的基本要求是数字的千位分隔符格式,但能处理许多组合(包括日期)的东西会更好。
我意识到微软的Ajax库提供了一个版本的String.Format()
,但我们不想要整个框架的开销。
如果你需要一个printf,请使用printf
看起来90%的评论者从未使用过比仅使用%d更复杂的格式的printf。我想知道他们如何输出例如货币值?
(213.3244).toFixed(2)
,其他语言有其他方法(C# 有 Decimal.Truncate()
,或者使用 Math.Round()
/Math.round()
)。许多语言中也包含文化信息。C# 中的 System.Globalization
就是一个例子,JavaScript 中的 (324).toLocaleString()
也是如此。这个答案只适用于 Node.js,而不适用于浏览器。考虑到问题没有指定是浏览器还是 node,这个答案对于该情况可能被认为是无用的(但对于其他人来说是有帮助的)。在这里,模板字符串是最好的解决方案。 - Lilly现在有一个名为locutus的包,它可以将其他语言的函数转换为JavaScript,例如php、python、ruby等。
const printf = require('locutus/php/strings/printf')
printf('Hello world');
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.
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));
export function stringFormat (str: string, ...args: string[]) {
return args.reduce((acc, curr, i) => acc.replace(new RegExp("\\{" + i + "\\}", 'g'), curr), str);
}
如果你只需要使用 %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
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'));
这不是sprintf
的精确副本;但是它更加相似且更有力量:https://github.com/anywhichway/stringformatter
使用此库格式化表达式采用内嵌的 Javascript 对象形式,例如:
format("I have {number: {currency: "$", precision:2}}.",50.2);
将返回"我有$50.20。"
。
这不是世界上最推荐的函数,但它可以工作。
如果你需要 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");
只需使用模板字符串和箭头函数即可。这甚至使它们具有可重复使用性。
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) );
String.padStart
。 (请参见https://dev59.com/jXE85IYBdhLWcg3wnU-p) - Nor.Z