首页 文章

如何使用逗号作为千位分隔符在JavaScript中打印数字

提问于
浏览
1267

我试图在JavaScript中打印一个整数,逗号为千位分隔符 . 例如,我想将数字1234567显示为"1,234,567" . 我该怎么做呢?

我是这样做的:

function numberWithCommas(x) {
    x = x.toString();
    var pattern = /(-?\d+)(\d{3})/;
    while (pattern.test(x))
        x = x.replace(pattern, "$1,$2");
    return x;
}

有更简单或更优雅的方式吗?如果它也适用于浮点数会很好,但这不是必需的 . 它不需要特定于语言环境来决定句点和逗号 .

30 回答

  • 1

    可以使用浏览器的 Intl 对象以国际友好的方式插入千位分隔符:

    Intl.NumberFormat().format(1234);
    // returns "1,234" if the user's locale is en_US, for example
    

    有关更多信息,请参阅MDN's article on NumberFormat,您可以指定区域设置行为或默认为用户的行为 . 这更加万无一失,因为它尊重当地的差异;许多国家使用句点来分隔数字,而逗号表示小数 .

    Intl.NumberFormat尚未在所有浏览器中提供,但它适用于最新的Chrome,Opera和IE . Firefox的下一个版本应该支持它 . Webkit似乎没有实现的时间表 .

  • 6

    我认为这是最短的正则表达式:

    /\B(?=(\d{3})+\b)/g
    
    "123456".replace(/\B(?=(\d{3})+\b)/g, ",")
    

    我检查了几个数字,它工作 .

  • 57

    在写这篇文章之前,我写了这篇文章 . 没有正则表达式,你可以真正理解代码 .

    $(function(){
      
      function insertCommas(s) {
    
        // get stuff before the dot
        var d = s.indexOf('.');
        var s2 = d === -1 ? s : s.slice(0, d);
    
        // insert commas every 3 digits from the right
        for (var i = s2.length - 3; i > 0; i -= 3)
          s2 = s2.slice(0, i) + ',' + s2.slice(i);
    
        // append fractional part
        if (d !== -1)
          s2 += s.slice(d);
    
        return s2;
    
      }
      
      
      $('#theDudeAbides').text( insertCommas('1234567.89012' ) );
      
      
    });
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    
    <div id="theDudeAbides"></div>
    
  • 31

    您可以使用此过程来格式化您需要的货币 .

    var nf = new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    });
    nf.format(123456.789); // ‘$123,456.79’
    

    有关详细信息,您可以访问此链接 .

    https://www.justinmccandless.com/post/formatting-currency-in-javascript/

  • 1

    这是@ mikez302的答案的变体,但修改为支持带小数的数字(根据@ neu-rah的反馈,numberWithCommas(12345.6789) - >“12,345.6,789”而不是“12,345.6789”

    function numberWithCommas(n) {
        var parts=n.toString().split(".");
        return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
    }
    
  • 18

    我认为这个功能将处理与此问题相关的所有问题 .

    function commaFormat(inputString) {
        inputString = inputString.toString();
        var decimalPart = "";
        if (inputString.indexOf('.') != -1) {
            //alert("decimal number");
            inputString = inputString.split(".");
            decimalPart = "." + inputString[1];
            inputString = inputString[0];
            //alert(inputString);
            //alert(decimalPart);
    
        }
        var outputString = "";
        var count = 0;
        for (var i = inputString.length - 1; i >= 0 && inputString.charAt(i) != '-'; i--) {
            //alert("inside for" + inputString.charAt(i) + "and count=" + count + " and outputString=" + outputString);
            if (count == 3) {
                outputString += ",";
                count = 0;
            }
            outputString += inputString.charAt(i);
            count++;
        }
        if (inputString.charAt(0) == '-') {
            outputString += "-";
        }
        //alert(outputString);
        //alert(outputString.split("").reverse().join(""));
        return outputString.split("").reverse().join("") + decimalPart;
    }
    
  • 2

    Using Regular expression

    function toCommas(value) {
        return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
    console.log(toCommas(123456789)); // 123,456,789
    
    console.log(toCommas(1234567890)); // 1,234,567,890
    console.log(toCommas(1234)); // 1,234
    

    Using toLocaleString()

    var number = 123456.789;
    
    // request a currency format
    console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
    // → 123.456,79 €
    
    // the Japanese yen doesn't use a minor unit
    console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
    // → ¥123,457
    
    // limit to three significant digits
    console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
    // → 1,23,000
    

    ref MDN:Number.prototype.toLocaleString()

    Using Intl.NumberFormat()

    var number = 123456.789;
    
    console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
    // expected output: "123.456,79 €"
    
    // the Japanese yen doesn't use a minor unit
    console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
    // expected output: "¥123,457"
    
    // limit to three significant digits
    console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));
    
    // expected output: "1,23,000"
    

    ref Intl.NumberFormat

    DEMO AT HERE

    <script type="text/javascript">
      // Using Regular expression
      function toCommas(value) {
        return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
      }
    
      function commas() {
        var num1 = document.myform.number1.value;
    
        // Using Regular expression
        document.getElementById('result1').value = toCommas(parseInt(num1));
        // Using toLocaleString()
    
        document.getElementById('result2').value = parseInt(num1).toLocaleString('ja-JP', {
          style: 'currency',
          currency: 'JPY'
        });
    
        // Using Intl.NumberFormat()
        document.getElementById('result3').value = new Intl.NumberFormat('ja-JP', {
          style: 'currency',
          currency: 'JPY'
        }).format(num1);
      }
    </script>
    <FORM NAME="myform">
      <INPUT TYPE="text" NAME="number1" VALUE="123456789">
      <br>
      <INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
      <br>Using Regular expression
      <br>
      <INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
      <br>Using toLocaleString()
      <br>
      <INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
      <br>Using Intl.NumberFormat()
      <br>
      <INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">
    
    </FORM>
    

    Performance

    Performance
    http://jsben.ch/sifRd

  • 2187

    Intl.NumberFormat

    原生JS功能 . 由IE11,Edge,最新的Safari,Chrome,Firefox,Opera,iOS上的Safari和Android上的Chrome提供支持 .

    var number = 3500;
    
    console.log(new Intl.NumberFormat().format(number));
    // → '3,500' if in US English locale
    
  • 65

    这是一个简单的函数,可以为千位分隔符插入逗号 . 它使用数组函数而不是RegEx .

    /**
     * Format a number as a string with commas separating the thousands.
     * @param num - The number to be formatted (e.g. 10000)
     * @return A string representing the formatted number (e.g. "10,000")
     */
    var formatNumber = function(num) {
        var array = num.toString().split('');
        var index = -3;
        while (array.length + index > 0) {
            array.splice(index, 0, ',');
            // Decrement by 4 since we just added another unit to the array.
            index -= 4;
        }
        return array.join('');
    };
    

    CodeSandbox链接示例:https://codesandbox.io/s/p38k63w0vq

  • 91

    我添加了tofixed到 Aki143S 的解决方案 . 此解决方案使用数千个分隔符的点和精度的逗号 .

    function formatNumber( num, fixed ) { 
        var decimalPart;
    
        var array = Math.floor(num).toString().split('');
        var index = -3; 
        while ( array.length + index > 0 ) { 
            array.splice( index, 0, '.' );              
            index -= 4;
        }
    
        if(fixed > 0){
            decimalPart = num.toFixed(fixed).split(".")[1];
            return array.join('') + "," + decimalPart; 
        }
        return array.join(''); 
    };
    

    例子;

    formatNumber(17347, 0)  = 17.347
    formatNumber(17347, 3)  = 17.347,000
    formatNumber(1234563.4545, 3)  = 1.234.563,454
    
  • 22

    如果您正在处理货币值和格式化很多,那么可能值得添加处理大量边缘情况和本地化的微小accounting.js

    // Default usage:
    accounting.formatMoney(12345678); // $12,345,678.00
    
    // European formatting (custom symbol and separators), could also use options object as second param:
    accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99
    
    // Negative values are formatted nicely, too:
    accounting.formatMoney(-500000, "£ ", 0); // £ -500,000
    
    // Simple `format` string allows control of symbol position [%v = value, %s = symbol]:
    accounting.formatMoney(5318008, { symbol: "GBP",  format: "%v %s" }); // 5,318,008.00 GBP
    
  • 1

    以下是编码较少的好解决方案......

    var y = "";
    var arr = x.toString().split("");
    for(var i=0; i<arr.length; i++)
    {
        y += arr[i];
        if((arr.length-i-1)%3==0 && i<arr.length-1) y += ",";
    }
    
  • 13

    Number.prototype.toLocaleString() 如果它是由所有浏览器(Safari)本地提供的话会很棒 .

    我检查了所有其他答案,但似乎没有人填充它 . 这是对此的poc,实际上是前两个答案的组合;如果 toLocaleString 工作则使用它,如果它不使用自定义功能 .

    var putThousandsSeparators;
    
    putThousandsSeparators = function(value, sep) {
      if (sep == null) {
        sep = ',';
      }
      // check if it needs formatting
      if (value.toString() === value.toLocaleString()) {
        // split decimals
        var parts = value.toString().split('.')
        // format whole numbers
        parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep);
        // put them back together
        value = parts[1] ? parts.join('.') : parts[0];
      } else {
        value = value.toLocaleString();
      }
      return value;
    };
    
    alert(putThousandsSeparators(1234567.890));
    
  • 2

    我建议使用phpjs.org的number_format()

    function number_format(number, decimals, dec_point, thousands_sep) {
        // http://kevin.vanzonneveld.net
        // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +     bugfix by: Michael White (http://getsprink.com)
        // +     bugfix by: Benjamin Lupton
        // +     bugfix by: Allan Jensen (http://www.winternet.no)
        // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
        // +     bugfix by: Howard Yeend
        // +    revised by: Luke Smith (http://lucassmith.name)
        // +     bugfix by: Diogo Resende
        // +     bugfix by: Rival
        // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
        // +   improved by: davook
        // +   improved by: Brett Zamir (http://brett-zamir.me)
        // +      input by: Jay Klehr
        // +   improved by: Brett Zamir (http://brett-zamir.me)
        // +      input by: Amir Habibi (http://www.residence-mixte.com/)
        // +     bugfix by: Brett Zamir (http://brett-zamir.me)
        // +   improved by: Theriault
        // +   improved by: Drew Noakes
        // *     example 1: number_format(1234.56);
        // *     returns 1: '1,235'
        // *     example 2: number_format(1234.56, 2, ',', ' ');
        // *     returns 2: '1 234,56'
        // *     example 3: number_format(1234.5678, 2, '.', '');
        // *     returns 3: '1234.57'
        // *     example 4: number_format(67, 2, ',', '.');
        // *     returns 4: '67,00'
        // *     example 5: number_format(1000);
        // *     returns 5: '1,000'
        // *     example 6: number_format(67.311, 2);
        // *     returns 6: '67.31'
        // *     example 7: number_format(1000.55, 1);
        // *     returns 7: '1,000.6'
        // *     example 8: number_format(67000, 5, ',', '.');
        // *     returns 8: '67.000,00000'
        // *     example 9: number_format(0.9, 0);
        // *     returns 9: '1'
        // *    example 10: number_format('1.20', 2);
        // *    returns 10: '1.20'
        // *    example 11: number_format('1.20', 4);
        // *    returns 11: '1.2000'
        // *    example 12: number_format('1.2000', 3);
        // *    returns 12: '1.200'
        var n = !isFinite(+number) ? 0 : +number, 
            prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
            sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
            dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
            toFixedFix = function (n, prec) {
                // Fix for IE parseFloat(0.55).toFixed(0) = 0;
                var k = Math.pow(10, prec);
                return Math.round(n * k) / k;
            },
            s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
        if (s[0].length > 3) {
            s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
        }
        if ((s[1] || '').length < prec) {
            s[1] = s[1] || '';
            s[1] += new Array(prec - s[1].length + 1).join('0');
        }
        return s.join(dec);
    }
    

    UPDATE 02/13/14

    人们一直在报告这不能按预期工作,所以我做了一个包含自动化测试的JS Fiddle .

    Update 26/11/2017

    这里的小提琴作为一个稍微修改输出的Stack Snippet:

    function number_format(number, decimals, dec_point, thousands_sep) {
        // http://kevin.vanzonneveld.net
        // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +     bugfix by: Michael White (http://getsprink.com)
        // +     bugfix by: Benjamin Lupton
        // +     bugfix by: Allan Jensen (http://www.winternet.no)
        // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
        // +     bugfix by: Howard Yeend
        // +    revised by: Luke Smith (http://lucassmith.name)
        // +     bugfix by: Diogo Resende
        // +     bugfix by: Rival
        // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
        // +   improved by: davook
        // +   improved by: Brett Zamir (http://brett-zamir.me)
        // +      input by: Jay Klehr
        // +   improved by: Brett Zamir (http://brett-zamir.me)
        // +      input by: Amir Habibi (http://www.residence-mixte.com/)
        // +     bugfix by: Brett Zamir (http://brett-zamir.me)
        // +   improved by: Theriault
        // +   improved by: Drew Noakes
        // *     example 1: number_format(1234.56);
        // *     returns 1: '1,235'
        // *     example 2: number_format(1234.56, 2, ',', ' ');
        // *     returns 2: '1 234,56'
        // *     example 3: number_format(1234.5678, 2, '.', '');
        // *     returns 3: '1234.57'
        // *     example 4: number_format(67, 2, ',', '.');
        // *     returns 4: '67,00'
        // *     example 5: number_format(1000);
        // *     returns 5: '1,000'
        // *     example 6: number_format(67.311, 2);
        // *     returns 6: '67.31'
        // *     example 7: number_format(1000.55, 1);
        // *     returns 7: '1,000.6'
        // *     example 8: number_format(67000, 5, ',', '.');
        // *     returns 8: '67.000,00000'
        // *     example 9: number_format(0.9, 0);
        // *     returns 9: '1'
        // *    example 10: number_format('1.20', 2);
        // *    returns 10: '1.20'
        // *    example 11: number_format('1.20', 4);
        // *    returns 11: '1.2000'
        // *    example 12: number_format('1.2000', 3);
        // *    returns 12: '1.200'
        var n = !isFinite(+number) ? 0 : +number, 
            prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
            sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
            dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
            toFixedFix = function (n, prec) {
                // Fix for IE parseFloat(0.55).toFixed(0) = 0;
                var k = Math.pow(10, prec);
                return Math.round(n * k) / k;
            },
            s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
        if (s[0].length > 3) {
            s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
        }
        if ((s[1] || '').length < prec) {
            s[1] = s[1] || '';
            s[1] += new Array(prec - s[1].length + 1).join('0');
        }
        return s.join(dec);
    }
    
    var exampleNumber = 1;
    function test(expected, number, decimals, dec_point, thousands_sep)
    {
        var actual = number_format(number, decimals, dec_point, thousands_sep);
        console.log(
            'Test case ' + exampleNumber + ': ' +
            '(decimals: ' + (typeof decimals === 'undefined' ? '(default)' : decimals) +
            ', dec_point: "' + (typeof dec_point === 'undefined' ? '(default)' : dec_point) + '"' +
            ', thousands_sep: "' + (typeof thousands_sep === 'undefined' ? '(default)' : thousands_sep) + '")'
        );
        console.log('  => ' + (actual === expected ? 'Passed' : 'FAILED') + ', got "' + actual + '", expected "' + expected + '".');
        exampleNumber++;
    }
    
    test('1,235',    1234.56);
    test('1 234,56', 1234.56, 2, ',', ' ');
    test('1234.57',  1234.5678, 2, '.', '');
    test('67,00',    67, 2, ',', '.');
    test('1,000',    1000);
    test('67.31',    67.311, 2);
    test('1,000.6',  1000.55, 1);
    test('67.000,00000', 67000, 5, ',', '.');
    test('1',        0.9, 0);
    test('1.20',     '1.20', 2);
    test('1.2000',   '1.20', 4);
    test('1.200',    '1.2000', 3);
    
    .as-console-wrapper {
      max-height: 100% !important;
    }
    
  • 9

    已经有很多好的答案了 . 这是另一个,只是为了好玩:

    function format(num, fix) {
        var p = num.toFixed(fix).split(".");
        return p[0].split("").reduceRight(function(acc, num, i, orig) {
            if ("-" === num && 0 === i) {
                return num + acc;
            }
            var pos = orig.length - i - 1
            return  num + (pos && !(pos % 3) ? "," : "") + acc;
        }, "") + (p[1] ? "." + p[1] : "");
    }
    

    一些例子:

    format(77.03453, 2); // "77.03"
    format(78436589374); // "78,436,589,374"
    format(784, 4);      // "784.0000"
    format(-123456);     // "-123,456"
    
  • 30

    来自@ user1437663的解决方案非常棒 .

    谁真正了解解决方案正准备理解复杂的正则表达式 .

    一个小的改进,使其更具可读性:

    function numberWithCommas(x) {
        var parts = x.toString().split(".");
        return parts[0].replace(/\B(?=(\d{3})+(?=$))/g, ",") + (parts[1] ? "." + parts[1] : "");
    }
    

    该模式以 \B 开头,以避免在单词的开头使用逗号 . 有趣的是,模式返回为空,因为 \B 没有提前"cursor"(同样适用于 $ ) .

    O \B 之后是一个鲜为人知的资源,但它是Perl正则表达式的强大功能 .

    Pattern1 (? = (Pattern2) ).
    

    神奇的是括号中的内容(Pattern2)是一个跟随前一个模式(Pattern1)的模式,但没有推进光标,也不是返回模式的一部分 . 这是一种未来的模式 . 当有人期待但真的不走路时,情况就像这样!

    在这种情况下,pattern2是

    \d{3})+(?=$)
    

    它表示3位数(一次或多次),后跟字符串的结尾($)

    最后, Replace 方法更改所有出现的模式(空字符串)以用于逗号 . 这只发生在剩余部分是3位数的倍数的情况下(未来光标到达原点的末尾的情况) .

  • 189

    让我试着改善uKolkaanswer,也许可以帮助别人节省一些时间 .

    使用Numeral.js .

    document.body.textContent = numeral(1234567).format('0,0');
    
    <script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>
    

    只有当browser compatibilty不是问题时,才应该使用Number.prototype.toLocaleString() .

  • 12

    对我来说,最好的答案是像一些成员所说的那样使用toLocaleString . 如果你想要包含'$'符号,只需添加语言和类型选项 . 这是以及将数字格式化为墨西哥比索的示例

    var n = 1234567.22
    alert(n.toLocaleString("es-MX",{style:"currency", currency:"MXN"}))
    

    捷径

    1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})
    
  • 43

    我以为我会分享一些我用于大量格式化的小技巧 . 我没有插入逗号或空格,而是在“千”之间插入一个空但可见的 Span . 这使数千个容易看到,但它允许以原始格式复制/粘贴输入,没有逗号/空格 .

    // This function accepts an integer, and produces a piece of HTML that shows it nicely with 
    // some empty space at "thousand" markers. 
    // Note, these space are not spaces, if you copy paste, they will not be visible.
    function valPrettyPrint(orgVal) {
      // Save after-comma text, if present
      var period = orgVal.indexOf(".");
      var frac = period >= 0 ? orgVal.substr(period) : "";
      // Work on input as an integer
      var val = "" + Math.trunc(orgVal);
      var res = "";
      while (val.length > 0) {
        res = val.substr(Math.max(0, val.length - 3), 3) + res;
        val = val.substr(0, val.length - 3);
        if (val.length > 0) {
            res = "<span class='thousandsSeparator'></span>" + res;
        }
      }
      // Add the saved after-period information
      res += frac;
      return res;
    }
    

    有了这个CSS:

    .thousandsSeparator {
      display : inline;
      padding-left : 4px;
    }
    

    查看示例JSFiddle.

  • 4
    var number = 1234567890; // Example number to be converted
    

    ⚠请注意,javascript的maximum integer值为 9007199254740991


    toLocaleString

    number.toLocaleString(); // "1,234,567,890"
    
    // A more complex example: 
    var number2 = 1234.56789; // floating point example
    number2.toLocaleString(undefined, {maximumFractionDigits:2}) // "1,234.57"
    

    NumberFormat(不支持Safari):

    var nf = new Intl.NumberFormat();
    nf.format(number); // "1,234,567,890"
    

    根据我的检查(至少是Firefox),它们在性能方面或多或少相同 .

  • 12
    function formatNumber (num) {
        return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
    }
    
    print(formatNumber(2665));      // 2,665
    print(formatNumber(102665));    // 102,665
    print(formatNumber(111102665)); // 111,102,665
    
  • 5

    我认为你的解决方案是我见过的较短的解决方案之一 . 我不认为有任何标准的JavaScript函数来做这种事情,所以你可能是你自己的 .

    我检查了CSS 3规范,看看是否可以在CSS中执行此操作,但除非您想要自己的 <span> 中的每个数字,否则我不可能 .

    我确实在Google Code上发现了一个看起来很有希望的项目:flexible-js-formatting . 我没有使用它,但它看起来非常灵活,并使用JsUnit进行单元测试 . 开发人员也有很多关于这个主题的帖子(虽然很旧) .

    请务必考虑国际用户:许多国家/地区使用空格作为分隔符,并使用逗号将小数与数字的整数部分分开 .

  • 3

    我使用了克里答案的想法,但简化了它,因为我只是为了我的特定目的而寻找简单的东西 . 这是我做的:

    function numberWithCommas(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
    

    这是你真正需要知道的 .

    @Neils Bom询问了正则表达式的工作原理 . 我的解释有点长 . 它不适合评论,我不知道在哪里放,所以我在这里做 . 如果有人有任何其他建议,请告诉我 .

    正则表达式使用2个前瞻断言:一个正向查找字符串中的任何一个点,后面有一个3位数的倍数,以及一个负断言,以确保该点只有3个数字的倍数 . 替换表达式在那里放一个逗号 .

    例如,如果你传递它“123456789.01”,正断言将匹配7左边的每个点(因为“789”是3位数的倍数,“678”是3位数的倍数,“567”,等等 . ) . 否定断言检查3位数的倍数后面没有任何数字 . “789”之后有一段时间,所以它正好是3位数的倍数,所以逗号就在那里 . “678”是3位数的倍数,但它后面有一个“9”,所以这3位数是4组的一部分,逗号不会去那里 . 同样对于“567” . “456789”是6位数,是3的倍数,所以在此之前使用逗号 . “345678”是3的倍数,但它后面有一个“9”,所以没有逗号 . 等等 . “\ B”使正则表达式不会在字符串的开头加上逗号 .

    @ neu-rah提到如果小数点后面有3位以上的数字,这个函数会在不受欢迎的地方添加逗号 . 如果这是一个问题,您可以使用此功能:

    function numberWithCommas(x) {
        var parts = x.toString().split(".");
        parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        return parts.join(".");
    }
    
  • 2
    var formatNumber = function (number) {
      var splitNum;
      number = Math.abs(number);
      number = number.toFixed(2);
      splitNum = number.split('.');
      splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
      return splitNum.join(".");
    }
    
  • 8

    另一种方法,支持小数,不同的分隔符和负数 .

    var number_format = function(number, decimal_pos, decimal_sep, thousand_sep) {
        var ts      = ( thousand_sep == null ? ',' : thousand_sep )
            , ds    = ( decimal_sep  == null ? '.' : decimal_sep )
            , dp    = ( decimal_pos  == null ? 2   : decimal_pos )
    
            , n     = Math.abs(Math.ceil(number)).toString()
    
            , i     = n.length % 3 
            , f     = n.substr(0, i)
        ;
    
        if(number < 0) f = '-' + f;
    
        for(;i<n.length;i+=3) {
            if(i!=0) f+=ts;
            f+=n.substr(i,3);
        }
    
        if(dp > 0) 
            f += ds + number.toFixed(dp).split('.')[1]
    
        return f;
    }
    
  • 1165

    这是我的尝试:

    编辑:小数点后添加

    function splitMille(n, separator = ',') {
      // Cast to string
      let num = (n + '')
    
      // Test for and get any decimals (the later operations won't support them)
      let decimals = ''
      if (/\./.test(num)) {
        // This regex grabs the decimal point as well as the decimal numbers
        decimals = num.replace(/^.*(\..*)$/, '$1')
      }
      
      // Remove decimals from the number string
      num = num.replace(decimals, '')
        // Reverse the number string through Array functions
        .split('').reverse().join('')
        // Split into groups of 1-3 characters (with optional supported character "-" for negative numbers)
        .match(/[0-9]{1,3}-?/g)
        // Add in the mille separator character and reverse back
        .join(separator).split('').reverse().join('')
    
      // Put the decimals back and output the formatted number
      return `${num}${decimals}`
    }
    
    let testA = splitMille(1234)
    let testB = splitMille(-1234)
    let testC = splitMille(123456.789)
    let testD = splitMille(9007199254740991)
    let testE = splitMille(1000.0001)
    
    console.log('Results!\n\tA: %s\n\tB: %s\n\tC: %s\n\tD: %s\n\tE: %s', testA, testB, testC, testD, testE)
    
  • 1

    感谢大家的回复 . 我已经 Build 了一些答案,以制定更“一刀切”的解决方案 .

    第一个片段添加了一个模拟PHPnumber_format() 到Number原型的函数 . 如果我格式化一个数字,我通常需要小数位,所以该函数需要显示小数位数 . 有些国家使用逗号作为十进制和小数作为千位分隔符,因此该函数允许设置这些分隔符 .

    Number.prototype.numberFormat = function(decimals, dec_point, thousands_sep) {
        dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
        thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';
    
        var parts = this.toFixed(decimals).split('.');
        parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_sep);
    
        return parts.join(dec_point);
    }
    

    您将使用如下:

    var foo = 5000;
    console.log(foo.numberFormat(2)); // us format: 5,000.00
    console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00
    

    我发现我经常需要为数学运算得到数字,但是parseFloat将5,000转换为5,只需取第一个整数值序列 . 所以我创建了自己的浮点转换函数并将其添加到String原型中 .

    String.prototype.getFloat = function(dec_point, thousands_sep) {
        dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
        thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';
    
        var parts = this.split(dec_point);
        var re = new RegExp("[" + thousands_sep + "]");
        parts[0] = parts[0].replace(re, '');
    
        return parseFloat(parts.join(dec_point));
    }
    

    现在您可以使用以下两种功能:

    var foo = 5000;
    var fooString = foo.numberFormat(2); // The string 5,000.00
    var fooFloat = fooString.getFloat(); // The number 5000;
    
    console.log((fooString.getFloat() + 1).numberFormat(2)); // The string 5,001.00
    
  • 1

    我很惊讶没人提到Number.prototype.toLocaleString . 它主要支持主流浏览器's implemented in JavaScript 1.5 (which was introduced in 1999) so it' .

    var n = 34523453.345
    n.toLocaleString()
    "34,523,453.345"
    

    通过包含Intl,它也适用于v0.12的Node.js

    注意这个函数返回字符串而不是数字

    如果你想要不同的东西,Numeral.js可能会很有趣 .

  • 15

    如果您在删除时选择范围,我也可以使用've adapted your code to work in TextBox (Input type= 377295 ) so we can enter and delete digits in real time without losing cursor. It' . 您可以自由使用箭头和主页/结束按钮 .
    谢谢你节省我的时间!

    //function controls number format as "1,532,162.3264321"
    function numberWithCommas(x) {
        var e = e || window.event;
        if (e.keyCode >= '35' && e.keyCode <= '40') return; //skip arrow-keys
        var selStart = x.selectionStart, selEnd = x.selectionEnd; //save cursor positions
        var parts = x.value.toString().split(".");
        var part0len = parts[0].length; //old length to check if new ',' would be added. Need for correcting new cursor position (+1 to right).
    
        //if user deleted ',' - remove previous number instead (without selection)
        if (x.selectionLength == 0 && (e.keyCode == 8 || e.keyCode == 46)) {//if pressed 8-backspace or 46-delete button
            var delPos = parts[0].search(/\d{4}/);
            if (delPos != -1) {//if found 4 digits in a row (',' is deleted)
                if (e.keyCode == 8) {//if backspace flag
                    parts[0] = parts[0].slice(0, selStart - 1) + parts[0].slice(selEnd, parts[0].length);
                    selEnd--;
                    if (selStart > selEnd) selStart = selEnd;
                } else {
                    parts[0] = parts[0].slice(0, selStart) + parts[0].slice(selEnd + 1, parts[0].length);
                    selStart++;
                    if (selEnd < selStart) selEnd = selStart;
                }
            }
        }
    
       var hasMinus = parts[0][0] == '-';
       parts[0] = (hasMinus ? '-' : '') + parts[0].replace(/[^\d]*/g, ""); //I'd like to clear old ',' to avoid things like 1,2,3,5,634.443216
       parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); //sets ',' between each 3 digits
       if (part0len < parts[0].length) { //move cursor to right if added new ','
           selStart++;
           selEnd++;
       } else if (part0len > parts[0].length) { //..or if removed last one ','
           selStart--;
           selEnd--;
       }
       x.value = parts.join(".");
       x.setSelectionRange(selStart, selEnd); //restoring cursor position
    }
    function saveSelectionLength(x) {
        x.selectionLength = x.selectionEnd - x.selectionStart;
    }
    

    要使用它,只需添加两个事件 - onKeyUp和onKeyDown

    <asp:TextBox runat="server" ID="val" Width="180px" onKeyUp="numberWithCommas(this);" onKeyDown="saveSelectionLength(this);"/>
    
  • 2

    以下代码使用char扫描,因此没有正则表达式 .

    function commafy( num){
      var parts = (''+(num<0?-num:num)).split("."), s=parts[0], L, i=L= s.length, o='';
      while(i--){ o = (i===0?'':((L-i)%3?'':',')) 
                      +s.charAt(i) +o }
      return (num<0?'-':'') + o + (parts[1] ? '.' + parts[1] : ''); 
    }
    

    它表现出了良好的表现:http://jsperf.com/number-formatting-with-commas/5

    2015.4.26:当num <0时解决问题的次要修复 . 见https://jsfiddle.net/runsun/p5tqqvs3/

相关问题