关于格式化:如何在javascript中将逗号作为千位分隔符打印数字

How to print a number with commas as thousands separators in JavaScript

我正试图用带逗号的数千分隔符的javascript打印一个整数。例如,我想将数字1234567显示为"1234567"。我该怎么做呢?

我是这样做的:

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

有更简单或更优雅的方法吗?如果它也能和float一起工作,那就更好了,但这不是必需的。它不需要特定于区域设置来决定句点和逗号。


我使用了克里的回答,但简化了它,因为我只是为了我的特定目的寻找简单的东西。以下是我所做的:

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

这就是你真正需要知道的。

@NeilsBom问Regex如何工作。我的解释有点长。它不符合评论,我也不知道把它放在哪里,所以我在这里做。如果有人对把它放在哪里有其他建议,请告诉我。

regex使用两个lookahead断言:一个正数查找字符串中在其后面一行中有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",所以没有逗号。等等。""防止regex在字符串的开头加逗号。

@Neu-rah提到,如果小数点后的数字超过3位,则此函数会在不希望出现的位置添加逗号。如果这是一个问题,您可以使用此函数:

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


我很惊讶没人提到数字。原型。ToLocalString。它是在Javascript1.5中实现的(这是在1999年引入的),所以它基本上支持跨主要浏览器。

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

从v0.12起,它还通过包含intl在node.js中工作

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

如果您想要不同的东西,numeral.js可能会很有趣。


1
var number = 1234567890; // Example number to be converted

?请注意,javascript的最大整数值为9007199254740991

TelaCaleSouth:

1
2
3
4
5
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"

数字格式(不支持Safari):

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

根据我所检查的(至少是火狐),它们在性能方面或多或少是相同的。


我建议使用phpjs.org的数字格式()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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);
}

更新02/13/14

人们一直在报告这并不像预期的那样工作,所以我做了一个包含自动测试的JS小提琴。

更新日期:2017年11月26日

下面是一个稍微修改了输出的堆栈片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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);
1
2
3
.as-console-wrapper {
  max-height: 100% !important;
}


这是@mikez302答案的变体,但经过修改以支持带小数的数字(根据@neu rah的反馈,数字带逗号(12345.6789)->"12345.6789"而不是"12345.6789"

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


1
2
3
4
5
6
7
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


使用正则表达式

1
2
3
4
5
6
7
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

使用ToLocaleString()。

1
2
3
4
5
6
7
8
9
10
11
12
13
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

引用mdn:number.prototype.toLocaleString()

使用intl.numberFormat()。

1
2
3
4
5
6
7
8
9
10
11
12
13
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"

参考国际号码格式

在这里演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<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);
  }

<FORM NAME="myform">
  <INPUT TYPE="text" NAME="number1" VALUE="123456789">
 
  <INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
  Using Regular expression
 
  <INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
  Using toLocaleString()
 
  <INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
  Using Intl.NumberFormat()
 
  <INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">

</FORM>

性能

Performance网址:http://jsben.ch/sifrd


国际号码格式

本地JS函数。支持IE11、EDGE、最新Safari、Chrome、Firefox、Opera、iOS版Safari和Android版Chrome。

1
2
3
4
var number = 3500;

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


感谢大家的回复。我建立了一些答案来制定一个更"一刀切"的解决方案。

第一个片段向数字原型添加了一个模仿php的number_format()的函数。如果我正在格式化一个数字,我通常需要小数位,所以函数需要显示小数位的数目。有些国家使用逗号作为小数,使用小数作为千位分隔符,因此函数允许设置这些分隔符。

1
2
3
4
5
6
7
8
9
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);
}

您可以如下使用:

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

我发现我经常需要为数学运算返回数字,但parsefloat将5000转换为5,只需取第一个整数值序列。所以我创建了自己的float转换函数并将其添加到字符串原型中。

1
2
3
4
5
6
7
8
9
10
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));
}

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

1
2
3
4
5
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
2
3
/\B(?=(\d{3})+\b)/g

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

我在一些数字上查了一下,结果成功了。


如果所有浏览器(Safari)都是本地提供的,那么Number.prototype.toLocaleString()就太棒了。

我查了所有其他的答案,但似乎没有人多填。这里是一个POC,它实际上是前两个答案的组合;如果toLocaleString工作,它使用它,如果不工作,它使用自定义函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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));


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

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

有关更多信息,请参阅MDN关于数字格式的文章,您可以指定区域设置行为或用户的默认值。这有点简单,因为它尊重本地差异;许多国家使用句点分隔数字,而逗号表示小数。

Intl.NumberFormat还没有在所有浏览器中都可用,但它可以在最新的Chrome、Opera等浏览器中使用。火狐的下一个版本应该支持它。WebKit似乎没有实现的时间表。


您可以使用此过程设置所需的货币格式。

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

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

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


如果您要处理大量的货币值和格式设置,那么可能需要添加处理大量边缘案例和本地化的Tiny Accounting.js:

1
2
3
4
5
6
7
8
9
10
11
// 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


下面的代码使用char扫描,因此没有regex。

1
2
3
4
5
6
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://jspef.com/number-formatting-with-commas/5

2015.4.26:在num<0时解决问题的小修复。参见https://jsfiddle.net/runsun/p5tqqvs3/


下面是一个简单的函数,它为千位分隔符插入逗号。它使用数组函数而不是regex。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * 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


我写这篇文章之前,在这篇文章上跌跌撞撞。没有regex,您实际上可以理解代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$(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' ) );
 
 
});
1
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">


对我来说,最好的答案是像一些会员说的那样使用摇头丸。如果要包含"$"符号,只需添加languaje和type选项。下面是将数字格式化为墨西哥比索的示例

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

捷径

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

让我试着改进Ukolka的答案,也许可以帮助其他人节省一些时间。

使用Mulal.js。

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

您应该使用number.prototype.toLocaleString&40;&41;仅当它的浏览器兼容性不是问题时。


1
2
3
4
5
6
7
8
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(".");
}

编辑:该函数只能使用正数。对于Expple:

1
2
var number = -123123231232;
formatNumber(number)

输出:"123123231232"

但要回答上述问题,toLocaleString()方法只是解决了问题。

1
2
var number = 123123231232;
    number.toLocaleString()

输出:"123123231232"

加油!


我认为这个函数将处理与这个问题相关的所有问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
}

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

1
2
3
4
5
6
7
8
9
10
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] :"");
}

一些例子:

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


使用此代码处理印度的货币格式。可以更改国家代码以处理其他国家货币。

1
2
3
4
5
6
7
8
let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
  minimumFractionDigits: 2,
});

// Use it.

formatter.format(amount);

输出:

1
3,50,256.95


我认为你的解决方案是我见过的较短的方案之一。我不认为有任何标准的javascript函数可以完成这类工作,所以您可能是自己完成的。

我检查了CSS3规范,看看是否有可能在CSS中实现这一点,但是除非你想要它自己的中的每个数字,否则我认为这是不可能的。

我确实在谷歌代码上发现了一个有前途的项目:灵活的JS格式。我没有使用它,但它看起来相当灵活,并且有使用JSUnit的单元测试。开发人员也有很多关于这个主题的文章(尽管很旧)。

一定要考虑国际用户:许多国家使用空格作为分隔符,并使用逗号将小数与数字的整数部分分隔开。


我在AKI143S的溶液中加入了TOFIXED。此解决方案使用点作为千位分隔符,使用逗号作为精度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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('');
};

实例;

1
2
3
formatNumber(17347, 0)  = 17.347
formatNumber(17347, 3)  = 17.347,000
formatNumber(1234563.4545, 3)  = 1.234.563,454

@user1437663的解决方案非常好。

真正理解解决方案的人正在准备理解复杂的正则表达式。

一个小的改进使它更易读:

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

模式以开头,以避免在单词开头使用逗号。有趣的是,模式返回为空,因为没有前进"光标"(同样适用于$)。

OB后面跟着一个不太知名的资源,但它是Perl正则表达式的一个强大功能。

1
            Pattern1 (? = (Pattern2) ).

神奇的是,圆括号(pattern2)中的内容是遵循上一个模式(pattern1)的模式,但不前进光标,也不是返回的模式的一部分。这是一种未来的模式。当有人向前看,但实际上不走路时,这是相似的!

在这种情况下,模式2是

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

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

最后,replace方法将找到的模式(空字符串)的所有出现处更改为逗号。只有在剩余部分是3位数的倍数的情况下才会发生这种情况。(例如,未来光标到达原点的末端)。


我发现了一种适用于各种情况的方法。代码沙盒示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function commas(n) {
  if (n < 1000) {
    return n + ''
  } else {
    // Convert to string.
    n += ''

    // Skip scientific notation.
    if (n.indexOf('e') !== -1) {
      return n
    }

    // Support fractions.
    let i = n.indexOf('.')
    let f = i == -1 ? '' : n.slice(i)
    if (f) n = n.slice(0, i)

    // Add commas.
    i = n.length
    n = n.split('')
    while (i > 3) n.splice((i -= 3), 0, ',')
    return n.join('') + f
  }
}

这就像诺亚·弗雷塔斯的答案,但支持分数和科学记数法。

如果不考虑性能,我认为toLocaleString是最佳选择。

编辑:这里有一个代码沙盒和一些示例:https://codesandbox.io/s/zmvxjpj6x


在这里找不到一个现代和全面的解决方案之后,我编写了一个箭头函数(不带regex)来解决格式化问题,它允许调用者为欧洲和世界其他地区提供小数位数、句点和千位分隔符。

Examples:

1
2
3
numberFormatter(1234567890.123456) => 1,234,567,890
numberFormatter(1234567890.123456, 4) => 1,234,567,890.1235
numberFormatter(1234567890.123456, 4, '.', ',') => 1.234.567.890,1235 Europe

以下是用ES6(现代语法)编写的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const numberFormatter = (number, fractionDigits = 0, thousandSeperator = ',', fractionSeperator = '.') => {
    if (number!==0 && !number || !Number.isFinite(number)) return number
    const frDigits = Number.isFinite(fractionDigits)? Math.min(Math.max(fractionDigits, 0), 7) : 0
    const num = number.toFixed(frDigits).toString()

    const parts = num.split('.')
    let digits = parts[0].split('').reverse()
    let sign = ''
    if (num < 0) {sign = digits.pop()}
    let final = []
    let pos = 0

    while (digits.length > 1) {
        final.push(digits.shift())
        pos++
        if (pos % 3 === 0) {final.push(thousandSeperator)}
    }
    final.push(digits.shift())
    return `${sign}${final.reverse().join('')}${frDigits > 0 ? fractionSeperator : ''}${frDigits > 0 && parts[1] ? parts[1] : ''}`
}

它已被测试为负输入,不良输入和NAN情况。如果输入是NaN,那么它只返回它。


这里有一个支持int&decimal的单行函数。我留下了一些代码来将数字转换成字符串。

1
2
3
    function numberWithCommas(x) {
        return (x=x+'').replace(new RegExp('\\B(?=(\\d{3})+'+(~x.indexOf('.')?'\\.':'$')+')','g'),',');
    }

这是我的尝试:

编辑:以小数形式添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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!
\tA: %s
\tB: %s
\tC: %s
\tD: %s
\tE: %s'
, testA, testB, testC, testD, testE)


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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;
}


如果您碰巧使用AngularJS,那么这个货币过滤器肯定会有帮助:http://www.w3schools.com/angular/ng_filter_currency.asp


只针对未来的谷歌(或不一定是"谷歌"):

上面提到的所有解决方案都很好,但是,在这种情况下使用regexp可能是非常糟糕的事情。

因此,是的,您可以使用一些建议的选项,甚至编写一些原始但有用的内容,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const strToNum = str => {

   //Find 1-3 digits followed by exactly 3 digits & a comma or end of string
   let regx = /(\d{1,3})(\d{3}(?:,|$))/;
   let currStr;

   do {
       currStr = (currStr || str.split(`.`)[0])
           .replace( regx, `$1,$2`)
   } while (currStr.match(regx)) //Stop when there's no match & null's returned

   return ( str.split(`.`)[1] ) ?
           currStr.concat(`.`, str.split(`.`)[1]) :
           currStr;

};

strToNum(`123`) // => 123
strToNum(`123456`) // => 123,456
strToNum(`-1234567.0987`) // => -1,234,567.0987

这里使用的regexp相当简单,循环将精确执行完成任务所需的次数。

您可能会更好地优化它,"干燥"代码等等。

然而,

1
(-1234567.0987).toLocaleString();

(在大多数情况下)是一个更好的选择。

关键不在于执行速度或跨浏览器兼容性。

在您希望向用户显示结果编号的情况下,.ToLocaleString()方法使您能够与网站或应用程序的用户(无论其语言是什么)使用相同的语言。

根据EcmaScript文档,这种方法是在1999年引入的,我认为其原因是希望互联网在某一点上能够连接世界各地的人们,因此需要一些"内化"工具。

今天,互联网确实连接了我们所有人,因此,重要的是要记住,这个世界是一个更复杂的方式,我们可能会想象我们所有人都在互联网上。

显然,考虑到人的多样性,我们不可能保证每个人都有完美的用户体验,因为我们讲不同的语言,重视不同的事物等。正因为如此,尽可能多地将事物本地化更为重要。

因此,考虑到有一些特定的日期、时间、数字等表示标准,我们有一个工具来以最终用户首选的格式显示这些内容,那么不使用该工具(尤其是在我们希望向用户显示这些数据的情况下)是不是很少见,而且几乎是不负责任的?

对我来说,在这种情况下使用regexp而不是.toLocaleString()听起来有点像用javascript创建一个时钟应用程序,并以这种方式对其进行硬编码,这样它只显示布拉格时间(这对不住在布拉格的人来说是非常无用的),即使默认的行为是

1
new Date();

是根据最终用户的时钟返回数据。


我已经调整了您的代码以在文本框(input type="text")中工作,因此我们可以实时输入和删除数字,而不会丢失光标。如果您在删除时选择范围,它也可以工作。您可以自由使用箭头和主/结束按钮。
谢谢你节省我的时间!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//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

1
 


这里有一个很好的解决方案,代码更少…

1
2
3
4
5
6
7
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 +=",";
}


印度数字系统

1
2
3
var number ="323483.85"
var decimal = number.split(".");
var res = (decimal[0].length>3? numberWithCommas(decimal[0].substring(0,decimal[0].length-3))+ ',' :decimal[0]) + (decimal[0].length>3?decimal[0].substring(decimal[0].length-3,decimal[0].length):'') + '.' + decimal[1];

输出:3,23483.85


对于整数,我使用了一个非常简单的方法:

1
2
3
4
5
var myNumber = 99999,
    myString = myNumber +"";

myString.length > 3 ? return myString.substring(0, myString.length - 3) +"," +
    myString.substring(myString.length - 3) : return myString;


我想我会分享一个小技巧,用于大数字格式。我没有插入逗号或空格,而是在"千"之间插入一个空的但可见的跨距。这使得数千个字符很容易被看到,但它允许以原始格式复制/粘贴输入,而不需要逗号/空格。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 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:

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

请参阅一个JSfiddle示例。


1
2
3
4
5
6
7
8
9
10
11
12
13
function addCommas(nStr) {
    nStr += '';
    var x = nStr.split('.');
    var x1 = x[0];
    var x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
            x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

addCommas(parseFloat("1099920.23232").toFixed(2)); //Output  1,099,920.23

现在应该可以了…如果数字是小数,则编辑为添加小数点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  function makedollars(mynumber)
      {
       mynumber = mynumber.toString();
    var numberend="";

  if(mynumber.split('.').length>1){
       var mynumbersplit = mynumber.split('.');
     mynumber = mynumbersplit[0];
   numberend= mynumbersplit[1];

  }

      var  mn = mynumber.length;

      if (mn <= 3) { return mynumber + numberend; }
      var grps = [];

        while (mn > 3)
        {  
            grps.push(mynumber.substring(mn,mn - 3));
            mn = mn - 3;
        }
        grps.push(mynumber.substring(mn,mn - 3));
      grps.reverse();

        grps.join(",");
        if(numberend!=""){ grps =  grps +"."+numberend;}

        return grps;
              }


可以使用for循环将逗号添加到数字中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function convertNumber(){
    var _cash = cash.toString()
    var _formattedCash = ''
    var count = 0

    for (let i = _cash.length; i >= 0; i--) {
        _formattedCash += _cash.substring(i,i+1)

        if(count == 3 && i > 0){
            _formattedCash += ','
            count = 0
        }
        count++
    }

    var _format = ''

    for (let i = _formattedCash.length; i >= 0; i--) {
        _format += _formattedCash.substring(i, i + 1)
    }

    return 'Ksh ' + _format;
}


还有一个..(对于int的问题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function insertCommas(str)
{
    var a = str.split("");
    a.reverse();

    var t, i = 0, arr = Array();

    while (t = a.shift())
    {
       if (((i++ % 3) == 0) && arr.length > 0)
           arr.unshift(",");
       arr.unshift(t);
    }

    return arr.join("");
}

您可以使用printf方式,例如:

1
2
double number = 1234567;
System.out.printf("%,.2f" , number);