JavaScript 是否考虑了本地小数分隔符
Does JavaScript take local decimal separators into account?
我有一个网页,以用户的本地化格式显示小数,如下所示:
- 英语:
7.75
- 荷兰语:
7,75
如果我在我的机器上的 JavaScript 中将两个数字变量加在一起(其中数字取自上述格式的字符串),我会得到以下结果:
- 英语:
7.75 + 7.75 = 15.5
- 荷兰语:
7,75 + 7,75 = 0
如果我要在荷兰用户机器上运行此代码,我是否应该期望英语格式的添加返回0
,荷兰格式的添加返回15,5
?
简而言之:JavaScript 计算是否在其字符串到数字的转换中使用本地小数分隔符?
区域设置感知数字解析器的示例:
function parseLocaleNumber(stringNumber, locale) {
var thousandSeparator = Intl.NumberFormat(locale).format(11111).replace(/'p{Number}/gu, '');
var decimalSeparator = Intl.NumberFormat(locale).format(1.1).replace(/'p{Number}/gu, '');
return parseFloat(stringNumber
.replace(new RegExp('''' + thousandSeparator, 'g'), '')
.replace(new RegExp('''' + decimalSeparator), '.')
);
}
它使用传递的区域设置(如果未定义区域设置参数,则使用浏览器的当前区域设置)来替换千位和小数分隔符。
使用德语区域设置
var n = parseLocaleNumber('1.000.045,22');
n
将等于1000045.22
.
更新:
- 通过使用正则表达式类
'p{Number}
删除数字来解决 Pointy 的评论。因此它也适用于非阿拉伯数字。 - 解决了 Orion Adrian 的评论,以支持每四位数字分隔数字的语言。
- 添加了区域设置参数,用于区分不同的语言环境以进行解析。
不,分隔符在 javascript Number
中始终是一个点 (.) 。所以7,75
求值为 75
,因为,
调用从左到右的求值(在控制台中尝试:x=1,x+=1,alert(x)
,或者更准确地说var x=(7,75); alert(x);
)。如果要转换荷兰语(好吧,不仅是荷兰语,比方说欧洲大陆)格式的值,它应该是一个String
。您可以为String
原型编写扩展,如下所示:
String.prototype.toFloat = function(){
return parseFloat(this.replace(/,('d+)$/,'.$1'));
};
//usage
'7,75'.toFloat()+'7,75'.toFloat(); //=> 15.5
请注意,如果浏览器支持,您可以使用Number.toLocaleString
console.log((3.32).toLocaleString("nl-NL"));
console.log((3.32).toLocaleString("en-UK"));
.as-console-wrapper { top: 0; max-height: 100% !important; }
@naitsirch扩展解决方案,我们可以使用Intl.NumberFormat.formatToParts()让JS解析组和小数分隔符。
function parseLocaleNumber(stringNumber) {
let num = 123456.789,
fmt_local = new Intl.NumberFormat(),
parts_local = fmt_local.formatToParts(num),
group = '',
decimal = '';
parts_local.forEach(function(i) {
switch (i.type) {
case 'group':
group = i.value;
break;
case 'decimal':
decimal = i.value;
break;
default:
break;
}
});
return parseFloat(stringNumber
.replace(new RegExp('''' + group, 'g'), '')
.replace(new RegExp('''' + decimal), '.')
);
}
//replace this string with a number formatted for your locale
console.log(parseLocaleNumber("987,654,321.01"));
//output for "en" locale: 987654321.01
从@OXiGEN扩展解决方案,我们可以使用 Intl.NumberFormat.formatToParts() 也提取货币符号:)
function parseLocaleNumber(stringNumber, locale, currency_code) {
let num = 123456.789,
fmt_local = new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency_code
}),
parts_local = fmt_local.formatToParts(num),
group = '',
decimal = '',
currency = '';
// separators
parts_local.forEach(function(i) {
//console.log(i.type + ':' + i.value);
switch (i.type) {
case 'group':
group = i.value;
break;
case 'decimal':
decimal = i.value;
break;
case 'currency':
currency = i.value;
break;
default:
break;
}
});
return parseFloat(stringNumber
.replace(new RegExp('''' + group, 'g'), '')
.replace(new RegExp('''' + decimal), '.')
.replace(new RegExp('''' + currency, 'g'), '')
);
}
//replace inputs with a number formatted for your locale, your locale code, your currency code
console.log(parseLocaleNumber('$987,654,321.01', 'en', 'USD'));
//output for "en" locale and "USD" code: 987654321.01
不,逗号(,
)是一个具有特殊含义的运算符,就像点(.
)一样。否则事情很简单:
var array1 = [1,2];
var array2 = [1.2];
会在不同的区域设置下中断。我所知道的所有主流语言都分别对待.
和,
,无论区域设置如何。
不,小数分隔符在 JavaScript 中根本没有本地化,parseFloat() 解析数字的格式与您需要在 JavaScript 源代码中使用的格式相同:"." 作为小数分隔符,没有组(千)分隔符,"E"或"e"作为"乘以十次方"符号,Ascii 连字符"-"作为减号。
要以本地化格式读取或写入数字,您需要其他东西。我推荐 Globalize.js 库,除非您可以将自己限制在小数分隔符和有限数量的语言的单个问题上 - 在这种情况下,在输出时仅执行将"."映射到","的字符串操作可能更简单,反之亦然。
考虑到符号,这适用于所有情况:
parseLocaleNumber: function ( stringNumber )
{
let thousandSeparator = (11111).toLocaleString().replace(/1/g, '');
let decimalSeparator = (1.1).toLocaleString().replace(/1/g, '');
let symbol = (0).toLocaleString()
.replace(/0/g, '')
.replace(new RegExp('''' + decimalSeparator), '.')
.trim();
return parseFloat(
stringNumber
.replace(new RegExp('''' + thousandSeparator, 'g'), '')
.replace(new RegExp('''' + decimalSeparator), '.')
.replace(new RegExp( symbol ), '')
);
}
突出了 2 个细节:
- 使用 11111 而不是 1111,因为默认情况下第一个始终显示千位分隔符。
- 数字格式始终使用"."作为小数点分隔符
- 货币代码为欧元-金额的格式不应包含小数
- 键按正则表达式以查找具有负值的小数
- 将数字四舍五入到两位小数
- Javascript和RegEx:拆分并保留分隔符
- 用于Javascript中小数输入的Regex,小数前有1到3位,小数后有1到三位
- 不使用分隔符分解字符串
- 设置自动分隔符的自定义属性
- 不允许在文本框中使用小数
- 在javascript中使用小数
- 通过多个分隔符解析字符串
- 用分隔符分隔具有多个整数值的字符串的Javascript"重试错误的值
- 在数字字符串的最后两个数字上加上小数
- Javascript Regex-从价格中抓取分隔符
- 正则表达式,不允许在javascript中使用负数和小数以及零
- 基于多个分隔符计数项目
- RegEx将有理文字与小数匹配,但不完全有理文字除外
- JavaScript 是否考虑了本地小数分隔符
- 如何使用 Angular “数字”过滤器键入时在输入字段中设置带有千和小数分隔符的字符串格式
- Regex表示带小数和千位分隔符的数字
- JavaScript regex接受带有逗号分隔符(千位)和点分隔符(小数)的数字