将字符串与点或逗号作为十进制分隔符转换为JavaScript中的数字



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

"1、2"
110年000年,23岁'
100年1.23

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

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

先进行替换:

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,001.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

最新更新