我需要在 JavaScript 中使用可以在运行时定义的分隔符来格式化数字。
千位和小数分隔符的组合可能与特定区域设置不匹配。
有没有办法在 JavaScript 中提供千位和小数分隔符
toLocaleString()
?或者明确使用 NumberFormat
和我定义的值?
我看到使用区域设置代码的示例,以及一些使用其他值的示例(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString),但这些不包括我的用例。
一种选择是使用已知分隔符格式化为字符串,然后使用未知分隔符进行查找/替换。
function formatNum(num, separator, fraction) {
var str = num.toLocaleString('en-US');
str = str.replace(/\./, fraction);
str = str.replace(/,/g, separator);
return str;
}
formatNum(12342.2, "a", "x");
//12a342x2
如果使用逗号作为小数点分隔符(参数
fraction
),本页的原始答案将不起作用。这是有问题的,因为逗号被广泛用作小数点分隔符,例如在欧洲(西班牙、法国、挪威、捷克、丹麦...)。
为了使其工作,可以分两步完成替换,而不是使用分数符号的中间占位符:
function formatNum(num, separator, fraction) {
return num
.toLocaleString('en-US');
.replace(/\./, "<fraction>")
.replace(/,/g, separator)
.replace(/<fraction>/, fraction);
}
formatNum(12342.2, " ", ",");
//12 342,2
有一个名为
Intl.NumberFormat
的
formatToParts
方法,具有足够的粒度来正确执行此操作。
这里将所有千位分隔符更改为下划线:
const formatter = Intl.NumberFormat(undefined); // Undefined locale == use the user's resolved locale
const parts = formatter.formatToParts(123456789.987654321);
parts.filter(p => p.type === 'group').forEach(p => p.value = '_');
const formatted = parts.map(p => p.value).join('');
formatted // '123_456_789.988'
FWIW,
formatToParts()
返回值如下所示:
[{type: 'integer', value: '123'},
{type: 'group', value: ',' },
{type: 'integer', value: '456'},
{type: 'group', value: ',' },
{type: 'integer', value: '789'},
{type: 'decimal', value: '.' },
{type: 'fraction', value: '988'}]
..所以如果您需要调整小数点分隔符,也很简单。
如果 MDN 文档没有足够的细节 ecma 402 规范涵盖了这些部分。
如果您想要完全自定义的数字呈现方式,正确的答案是 Intl.NumberFormater。
但是,如果您想要的只是控制分组和小数部分的长度,那么有一个更简单(实际上更简单)的解决方案:
const num = (123.45).toLocaleString([], {
maximumFractionDigits: 2,
useGrouping: false,
});
空的区域设置数组会导致系统使用默认区域设置。 好处是您不必指定显式区域设置,从而使代码适合任何给定客户端的区域设置。