将带有点或逗号的字符串作为小数分隔符转换为JavaScript中的数字

And*_*rus 43 javascript jquery data-conversion string-parsing

输入元素包含数字a,其中逗号或点用作小数分隔符,空格可用于对数千个进行分组,如下所示:

'
1,2''110 000,23''100
1.23'

如何使用JavaScript将它们转换为浏览器中的浮点数?

使用jQuery和jQuery UI.Number(string)返回NaNparseFloat()在第一个空格或逗号处停止.

小智 44

首先替换:

parseFloat(str.replace(',','.').replace(' ',''))
Run Code Online (Sandbox Code Playgroud)

  • 这完全忽略了`,`通常用作千位分隔符(分组)的事实.如果你在"1,000,000.00"这样的数字上使用它,你会得到"1",这显然是完全错误的. (44认同)
  • @Zbynek我根本就没想到.大多数(如果不是所有语言/区域)都使用某些描述的数字分组.使用的字符各不相同(例如`[.,']`).我指出这样一个事实:这段代码忽略了大量的输入,这些输入会导致错误而答案中没有任何警告(并且无法知道它已经发生).即使您列出的语言不会出现这个问题,也不会否定********语言中存在的问题.请注意,如果所讨论的语言使用`.`作为其数字分组字符,它将同样被破坏. (11认同)
  • 这是迄今为止我遇到过的最糟糕的解决方案!SO是基于社区的,并且忽略了一个事实,即解决方案虽然适用于OP,但通常不是正确的答案.如果我在财务软件中使用此解决方案,我将入狱或被现在杀死.. (6认同)
  • 我认为这是一个不错的答案。我讨厌当用户尝试使用极端情况来尝试破坏对某人有用的好答案时。如果你的环境和客户可以保证,例如,文化是EN,或者不会像这样转换财务数据,那有什么大不了的?只有当代码是一把过度设计的瑞士军刀时,代码才“可接受”吗?@KemalEmin,这真的是一段糟糕的代码吗?有人会因此而被杀吗? (3认同)
  • @Zimano,如果它是预先的并且明确地强调了它的局限性,而不是将其本身描述为一个没有任何警告的简单解决方案,那么它_将_是一个不错的答案。事实上,当它失败时,它会悄无声息地、引人注目地失败,这一事实至少应该向那些正在寻找与最初问题所要求类似的解决方案的人发出警告。SO 的目的是为不仅仅是在他们所描述的情况下提出问题的人提供解决方案。 (3认同)
  • 我认为这种解决方案在很多情况下都不会起作用. (2认同)

小智 20

完美的解决方案

accounting.js 是一个很小的JavaScript库,用于数字,货币和货币格式.

检查这个参考


Tho*_*4no 17

我意识到我迟到了,但我想要一个解决方案,正确处理数字分组以及货币的不同小数分隔符.由于这些都没有完全覆盖我的用例,我编写了自己的解决方案,这可能对其他人有用:

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);
}
Run Code Online (Sandbox Code Playgroud)

这应该去掉任何非数字,然后检查是否有一个小数点(或逗号)后跟两位数字,并在需要时插入小数点.

值得注意的是,我专门针对货币设定了这种方式,因此它假设没有小数位或正好两位.很难确定遇到的第一个可能的小数点是小数点还是数字分组字符(例如,1.542可能1542),除非你知道当前语言环境的细节,但它应该很容易定制到你的通过更改\d{2}$为与小数点后的预期相匹配的特定用例.

  • 要支持负值,请在正则表达式中的 9 之后添加“\-”(转义减号)。它应该像 `var result = stringValue.replace(/[^0-9\-]/g, '');` (3认同)

Ale*_*pin 9

您可以用空字符串替换所有空格,所有逗号都用点替换,然后解析它.

var str = "110 000,23";
var num = parseFloat(str.replace(/\s/g, "").replace(",", "."));
console.log(num);
Run Code Online (Sandbox Code Playgroud)

我在第一个中使用正则表达式来匹配所有空格,而不仅仅是第一个空格.


stu*_*ney 7

这是最好的解决方案

http://numeraljs.com/

numeral().unformat('0.02'); = 0.02
Run Code Online (Sandbox Code Playgroud)


lpi*_*.eu 6

关于什么:

parseFloat(str.replace(' ', '').replace('.', '').replace(',', '.'));
Run Code Online (Sandbox Code Playgroud)


Sla*_*awa 6

所有其他解决方案都要求您提前了解格式。我需要检测(!)每种情况下的格式,这就是我最终得到的结果。

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;
}
Run Code Online (Sandbox Code Playgroud)

这是通过以下情况进行测试的:

        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,
        };
Run Code Online (Sandbox Code Playgroud)

欢迎提出建议。


小智 5

这是一个自给自足的 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
    }
}
Run Code Online (Sandbox Code Playgroud)


bco*_*ody 5

这是我的解决方案,没有任何依赖项:

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
Run Code Online (Sandbox Code Playgroud)

(我省略了对数字的转换 -parseFloat如果您不关心 JavaScript 的浮点数精度问题,那可能只是一个调用。)

该代码假设:

  • 仅使用逗号和句点作为小数点分隔符。(我不确定是否存在使用其他语言的语言环境。)
  • 字符串的小数部分不使用任何分隔符。