簡體   English   中英

將帶有點或逗號作為十進制分隔符的字符串轉換為 JavaScript 中的數字

[英]Convert String with Dot or Comma as decimal separator to number in JavaScript

輸入元素包含數字,其中逗號或點用作小數點分隔符,空格可用於將千位分組,如下所示:

'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 庫。

檢查這個以獲取參考

您可以用空字符串替換所有空格,用點替換所有逗號,然后解析它。

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調用。)

該代碼假設:

  • 只有逗號和句點用作小數點分隔符。 (我不確定是否存在使用其他語言環境的語言環境。)
  • 字符串的小數部分不使用任何分隔符。

試試這個...

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);

所以替換回調接受"1.000.000,00"並將其轉換為"1000000.00" 之后,結果字符串前面的+將其強制轉換為數字。

這個功能其實還蠻好用的。 例如,如果在回調函數中將p1 = ""部分替換為p1 = "" p1 = "," ,則輸入1.000.000,00將導致1,000,000.00

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM