输入元素包含数字,其中逗号或点用作小数分隔符,可以使用空格对千位进行分组,如下所示:
"1、2"
110年000年,23岁'
100年1.23
如何在浏览器中使用JavaScript将它们转换为浮点数?
使用jQuery和jQuery UI。Number(string)
返回NaN, parseFloat()
在第一个空格或逗号处停止。
先进行替换:
parseFloat(str.replace(',','.').replace(' ',''))
我意识到我迟到了,但我想要一个解决方案,正确处理数字分组以及不同的货币小数分隔符。由于这些都没有完全涵盖我的用例,所以我编写了自己的解决方案,这可能对其他人有用:
function parsePotentiallyGroupedFloat(stringValue) {
stringValue = stringValue.trim();
var result = stringValue.replace(/[^0-9]/g, '');
if (/[,.]d{2}$/.test(stringValue)) {
result = result.replace(/(d{2})$/, '.$1');
}
return parseFloat(result);
}
这应该去掉任何非数字,然后检查是否有一个小数点(或逗号)后面跟着两个数字,如果需要的话插入小数点。
值得注意的是,我是专门针对货币的,因此它要么没有小数点,要么恰好是两位。很难确定遇到的第一个潜在的小数点是小数点还是数字分组字符(例如,1.542
可能是1542
),除非您知道当前语言环境的具体情况,但是通过将d{2}$
更改为适当匹配小数点后的内容,应该很容易针对您的特定用例进行定制。
完美的解决方案
accounting.js
是一个小型的JavaScript库,用于数字,货币和货币格式。
检查ref
您可以将所有空格替换为空字符串,将所有逗号替换为点,然后解析它
var str = "110 000,23";
var num = parseFloat(str.replace(/s/g, "").replace(",", "."));
console.log(num);
我在第一个中使用了一个正则表达式来匹配所有空格,而不仅仅是第一个。
这是最好的解决方案
http://numeraljs.com/numeral().unformat('0.02'); = 0.02
怎么样:
parseFloat(str.replace(' ', '').replace('.', '').replace(',', '.'));
所有其他解决方案都要求您提前知道格式。我需要在每种情况下检测(!)格式,这就是我最终得到的。
function detectFloat(source) {
let float = accounting.unformat(source);
let posComma = source.indexOf(',');
if (posComma > -1) {
let posDot = source.indexOf('.');
if (posDot > -1 && posComma > posDot) {
let germanFloat = accounting.unformat(source, ',');
if (Math.abs(germanFloat) > Math.abs(float)) {
float = germanFloat;
}
} else {
// source = source.replace(/,/g, '.');
float = accounting.unformat(source, ',');
}
}
return float;
}
在以下情况下进行了测试:
const cases = {
"0": 0,
"10.12": 10.12,
"222.20": 222.20,
"-222.20": -222.20,
"+222,20": 222.20,
"-222,20": -222.20,
"-2.222,20": -2222.20,
"-11.111,20": -11111.20,
};
建议欢迎。
这是一个自给自足的JS函数,它解决了大多数欧洲/美国地区(主要是美国/德国/瑞典之间的数字分块和格式化)的这个(和其他)问题…如OP)。我认为这是对Slawa解决方案的改进(并受到启发),并且没有依赖关系。
function realParseFloat(s)
{
s = s.replace(/[^d,.-]/g, ''); // strip everything except numbers, dots, commas and negative sign
if (navigator.language.substring(0, 2) !== "de" && /^-?(?:d+|d{1,3}(?:,d{3})+)(?:.d+)?$/.test(s)) // if not in German locale and matches #,###.######
{
s = s.replace(/,/g, ''); // strip out commas
return parseFloat(s); // convert to number
}
else if (/^-?(?:d+|d{1,3}(?:.d{3})+)(?:,d+)?$/.test(s)) // either in German locale or not match #,###.###### and now matches #.###,########
{
s = s.replace(/./g, ''); // strip out dots
s = s.replace(/,/g, '.'); // replace comma with dot
return parseFloat(s);
}
else // try #,###.###### anyway
{
s = s.replace(/,/g, ''); // strip out commas
return parseFloat(s); // convert to number
}
}
这是我的解决方案,没有任何依赖:
return value
.replace(/[^d-.,]/g, "") // Basic sanitization. Allows '-' for negative numbers
.replace(/,/g, ".") // Change all commas to periods
.replace(/.(?=.*.)/g, ""); // Remove all periods except the last one
(我省略了到数字的转换-如果你不关心JavaScript的浮点数精度问题,那可能只是一个parseFloat
调用)
代码假设:
- 只使用逗号和句号作为小数分隔符。(我不确定是否存在使用其他区域的区域)
- 字符串的小数部分不使用任何分隔符。
try this…
var withComma = "23,3";
var withFloat = "23.3";
var compareValue = function(str){
var fixed = parseFloat(str.replace(',','.'))
if(fixed > 0){
console.log(true)
}else{
console.log(false);
}
}
compareValue(withComma);
compareValue(withFloat);
这个答案接受一些其他答案不接受的边缘情况:
- 只有千个分隔符:
1.000.000
=>1000000
- 指数:
1.000e3
=>1000e3
(100万)
运行代码片段以查看所有的测试套件。
const REGEX_UNWANTED_CHARACTERS = /[^d-.,]/g
const REGEX_DASHES_EXEPT_BEGINNING = /(?!^)-/g
const REGEX_PERIODS_EXEPT_LAST = /.(?=.*.)/g
export function formatNumber(number) {
// Handle exponentials
if ((number.match(/e/g) ?? []).length === 1) {
const numberParts = number.split('e')
return `${formatNumber(numberParts[0])}e${formatNumber(numberParts[1])}`
}
const sanitizedNumber = number
.replace(REGEX_UNWANTED_CHARACTERS, '')
.replace(REGEX_DASHES_EXEPT_BEGINING, '')
// Handle only thousands separator
if (
((sanitizedNumber.match(/,/g) ?? []).length >= 2 && !sanitizedNumber.includes('.')) ||
((sanitizedNumber.match(/./g) ?? []).length >= 2 && !sanitizedNumber.includes(','))
) {
return sanitizedNumber.replace(/[.,]/g, '')
}
return sanitizedNumber.replace(/,/g, '.').replace(REGEX_PERIODS_EXEPT_LAST, '')
}
function formatNumberToNumber(number) {
return Number(formatNumber(number))
}
const REGEX_UNWANTED_CHARACTERS = /[^d-.,]/g
const REGEX_DASHES_EXEPT_BEGINING = /(?!^)-/g
const REGEX_PERIODS_EXEPT_LAST = /.(?=.*.)/g
function formatNumber(number) {
if ((number.match(/e/g) ?? []).length === 1) {
const numberParts = number.split('e')
return `${formatNumber(numberParts[0])}e${formatNumber(numberParts[1])}`
}
const sanitizedNumber = number
.replace(REGEX_UNWANTED_CHARACTERS, '')
.replace(REGEX_DASHES_EXEPT_BEGINING, '')
if (
((sanitizedNumber.match(/,/g) ?? []).length >= 2 && !sanitizedNumber.includes('.')) ||
((sanitizedNumber.match(/./g) ?? []).length >= 2 && !sanitizedNumber.includes(','))
) {
return sanitizedNumber.replace(/[.,]/g, '')
}
return sanitizedNumber.replace(/,/g, '.').replace(REGEX_PERIODS_EXEPT_LAST, '')
}
const testCases = [
'1',
'1.',
'1,',
'1.5',
'1,5',
'1,000.5',
'1.000,5',
'1,000,000.5',
'1.000.000,5',
'1,000,000',
'1.000.000',
'-1',
'-1.',
'-1,',
'-1.5',
'-1,5',
'-1,000.5',
'-1.000,5',
'-1,000,000.5',
'-1.000.000,5',
'-1,000,000',
'-1.000.000',
'1e3',
'1e-3',
'1e',
'-1e',
'1.000e3',
'1,000e-3',
'1.000,5e3',
'1,000.5e-3',
'1.000,5e1.000,5',
'1,000.5e-1,000.5',
'',
'a',
'a1',
'a-1',
'1a',
'-1a',
'1a1',
'1a-1',
'1-',
'-',
'1-1'
]
document.getElementById('tbody').innerHTML = testCases.reduce((total, input) => {
return `${total}<tr><td>${input}</td><td>${formatNumber(input)}</td></tr>`
}, '')
<table>
<thead><tr><th>Input</th><th>Output</th></tr></thead>
<tbody id="tbody"></tbody>
</table>
从数字到货币字符串很容易通过number .prototype. tolocalestring。然而,反过来似乎是一个普遍的问题。JS标准中可能没有千位分隔符和小数点。
在这个特殊的问题中,千位分隔符是一个空格" "
,但在许多情况下,它可以是一个句点"."
,小数点可以是一个逗号","
。如1 000 000,00
、1.000.000,00
。这就是我如何把它转换成一个正确的浮点数。
var price = "1 000.000,99",
value = +price.replace(/(.|s)|(,)/g,(m,p1,p2) => p1 ? "" : ".");
console.log(value);
所以replacer回调接受"1.000.000,00"
并将其转换为"1000000.00"
。之后,结果字符串前面的+
将其强制转换为一个数字。
这个函数实际上非常方便。例如,如果您将回调函数中的p1 = ""
部分替换为p1 = ","
,则输入1.000.000,00
将得到1,000,000.00