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

Eli*_*ria 1589 javascript formatting numbers

我试图用逗号作为千位分隔符在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;
}
Run Code Online (Sandbox Code Playgroud)

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

Eli*_*ria 2597

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

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

这是你真正需要知道的.

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

  • 尝试numberWithCommas(12345.6789) - >"12,345.6,789"我不喜欢它 (56认同)
  • 这太棒了!感谢您将Kerry的答案提炼到我所需要的.谢谢!对于我最初的工作,这是一个更优雅的解决方案. (35认同)
  • 在"."之后修复的小改进.问题'123456789.01234'.replace(/\B(?=(?=\d*\.)(\ d {3})+(?!\ d))/ g,'_') (28认同)
  • 非常酷,但是注意到它在小数点后面有超过3个位置的数字有问题. (19认同)
  • 这在 Safari 中不起作用。破坏了我的整个应用程序并花了我很长时间才弄清楚这就是问题所在 (11认同)
  • @DmitrijGolubev不适用于整数.也许强制小数点将是解决方案. (7认同)
  • 它对分数不起作用,我们不希望在小数点后有逗号 (4认同)
  • Intl.NumberFormat()似乎更新一点,因为它使用locale doodads. (4认同)
  • @ yar1如果您打算在Safari中使用它,该怎么办?然后你只需要没有逗号就可以得到号码. (3认同)
  • 那好美丽 (2认同)
  • 多么美妙的解决方案啊。一个简单而漂亮的插件是将分隔符作为第二个参数,因为并不是每种语言中的数字都用逗号分隔。 (2认同)
  • 附加一个空字符串而不是调用.toString()通常会快一点,所以你可以__return(x +'').replace(/\B(?=(\ d {3})+(?!\ d))/g,','); __如果你传递null或undefined也不会抛出JS错误,但是类型转换确实意味着你将__undefined__转换为字符串'undefined'等等,这是值得注意的. (2认同)
  • 我会做一个追加vs .toString()的快速jsfiddle,但其他人先到了!如果你很好奇http://jsperf.com/tostring-vs-appending-empty-string/3 (2认同)
  • 投反对票,因为答案应该只是 Number(n).toLocaleString() (2认同)
  • 如果添加零小数,例如 0.30000000004,它将返回 0.30,000,000,004 (2认同)
  • 下面的答案 num.toLocaleString() 更正确,因为它是内置的,并且因为它考虑了文化差异。欧洲在数字中使用逗号与美国不同 (2认同)
  • 现在 JavaScript 正在向后查找,小数后的数字部分可以在正则表达式中解决,而不是使用 `split` 和 `join`: `.replace(/\B(?<!\.\d*) (?=(\d{3})+(?!\d))/g, ",")`。我也更新了答案以表明这一点。作为一个可变长度的lookbehind,我担心性能,但它[击败了`split`和`join`](http://jsben.ch/umq99)。 (2认同)
  • @TJCrowder 它在 Safari 中中断``无效的正则表达式:无效的组说明符名称``` (2认同)
  • 不是一个好的解决方案!使用“toLocaleString()”并停止以北美为中心。啊。 (2认同)
  • 请小心这段代码。它在火狐浏览器中不起作用 (2认同)
  • @EliasZamaria 事实上,它给寻求者带来了问题。我认为这不应该被删除,而是应该像这样编辑:tjcrowder 指出有一个最前沿的方法可以解决这个问题。请注意,某些现代浏览器仍然不支持它 - 支持信息)!现代 JavaScript 具有lookbehind,它可以在正则表达式本身中解决...... (2认同)
  • 我认为添加一个链接到 `toLocaleString`,[uKolka](/sf/answers/1236471001/) 的答案或解释为什么这可能比该函数更好会很好。 (2认同)
  • 此解决方案不适用于 safari 和 iPhone chrome。它会破坏您的整个应用程序,并且很难在移动设备中进行调试。请考虑否决此解决方案以节省人们的时间。 (2认同)

uKo*_*lka 1603

我很惊讶没人提到Number.prototype.toLocaleString.它是在JavaScript 1.5(1999年推出)中实现的,因此基本上支持主流浏览器.

var n = 34523453.345
n.toLocaleString()
"34,523,453.345"
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 似乎在Safari中也不起作用. (50认同)
  • 根据具体情况,性能差异可能是也可能不是问题.如果用于1000个结果的巨型表格,那么它将更重要,但如果仅用于单个值,则差异可以忽略不计.但优点是它具有区域设置意识,因此欧洲有人会看到_34.523.453,345_或_34 523 453,345_.这对于来自许多国家/地区的访问者来说更为重要. (20认同)
  • googlers的更新:`toLocaleString`通过[包含Intl](https://github.com/nodejs/node-v0.x-archive/pull/7719)在v0.12中的Node.js中工作. (20认同)
  • @csigrist好点,但它没有看起来那么糟糕.速度取决于浏览器.在FF或Opera中它表现良好.我虽然糟透了Chrome.至于零:`var number = 123456.000; number.toLocaleString('en-US',{minimumFractionDigits:2}); "123,456.00"`这些选项在FF或Safari中不起作用. (17认同)
  • @MSC你应该尝试`parseInt("1234567",10).toLocaleString('en-US',{minimumFractionDigits:2})`或`new Number("1234567").toLocaleString('en-US',{minimumFractionDigits :2})`而不是.它不起作用,因为你在字符串上使用它,而不是数字. (6认同)
  • 真棒.最后回答本机功能.而且,这个在不同的国家有不同的分隔符显示(在捷克共和国,我们写'X XXX XXX,YYY`). (4认同)
  • 我投了赞成票,但经过进一步研究发现这个答案存在一些问题.性能不如正则表达式格式化程序.请参阅以下链接:http://jsperf.com/number-formatting-with-commas.同时尝试将尾随零作为小数位也是有问题的. (2认同)
  • 这不适用于iPhone上的Chrome或Safari. (2认同)
  • 对于`var n = 12345.54321`,Chrome打印`12,345.543`没有2位小数. (2认同)
  • @curiosu 请阅读文档和以前的评论。`变量编号 = 12345.54321; number.toLocaleString('en-US', {maximumFractionDigits: 10});` (2认同)
  • OP 要求使用彗差分隔符。由于许多语言不使用逗号作为千位分隔符,因此您可能需要使用具有逗号分隔符的特定语言:`toLocaleString('en')` (2认同)
  • @A-Diddy 刚刚在 Chrtome 61 中尝试过这个,效果很好 (2认同)
  • 笔记。如果您正在开发 React Native 应用程序,这不适用于 Android。 (2认同)
  • **注意:** 您可能需要先将数字字符串转换为 int 或 float,即 `parseInt(123456, 10).toLocaleString()` 或 `parseFloat(123456.789012, 10).toLocaleString()`。另外,在后一种情况下,`.toLocaleString()`将默认限制小数位数。 (2认同)

vsy*_*ync 222

var number = 1234567890; // Example number to be converted
Run Code Online (Sandbox Code Playgroud)

⚠请注意,javascript的最大整数值为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"
Run Code Online (Sandbox Code Playgroud)


NumberFormat(不支持 Safari):

var nf = new Intl.NumberFormat();
nf.format(number); // "1,234,567,890"
Run Code Online (Sandbox Code Playgroud)

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

  • 对于那些在那里实施的人,Safari不支持NumberFormat. (6认同)
  • 在safari上也不支持toLocaleString (6认同)
  • 基本的`toLocaleString`适用于safari,选项不适用 (5认同)
  • 浏览器支持始终在每个MDN页面的底部提及,我已链接到该页面. (3认同)
  • `toLocaleString`解决方案可能还应该包含所需的语言环境,所以`toLocaleString("en")`,因为英语模式使用逗号.但是,如果没有语言环境指示符的`toLocaleString()`在法国运行,那么它将产生句号而不是逗号,因为这是用于在本地分离数千个的. (3认同)

Ker*_*nes 104

我建议使用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);
}
Run Code Online (Sandbox Code Playgroud)

更新02/13/14

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

更新于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);
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper {
  max-height: 100% !important;
}
Run Code Online (Sandbox Code Playgroud)

  • @ernix - 运营商要求JavaScript,我给出的答案是*JavaScript.这是PHP函数的JavaScript解释. (12认同)
  • @ernix - 好的,但问题是它确实*确切地说是OP所要求的.它来自另一个站点(不是由我维护,我之前已经说过),并且在给出适当的变量时,它的工作方式完全如上所述.如果您认为这是一个错误,请联系phpjs.org或查看他们是否有更新版本. (4认同)
  • @Andrew S - 只有一个人将其标记下来.它确实有效,我已多次在我自己的代码中使用它.它也不是我的代码(也不是我的测试),我引用了它来自的网站,这是一个众所周知的网站.也许他们有更新版本)因为您正在查看的代码是3年. (3认同)
  • @ernix - 它与OP给出的示例完全一样.我放了一个小提琴,你可以看到. (2认同)

小智 70

这是@ 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] : "");
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿看,[你是一个开源贡献者](https://github.com/text-mask/text-mask/blob/132e795daffdb866baa41a84079224772eaa0c24/addons/src/createNumberMask.js#L144) :) (8认同)

Tut*_*men 63

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

  • 它更短:) (8认同)
  • 这很优雅.正是我在寻找什么. (4认同)
  • 来自http://blog.tompawlak.org/number-currency-formatting-javascript?已知问题:formatNumber(0.123456)= 0.123,456 JS中没有lookbehind使得用优雅的正则表达式修复它很困难. (4认同)
  • 123456789.123456789.toString().replace(/(\d)(?=(\d{3})+\.)/g, '$1,') =&gt; 123,456,789.12345679 (2认同)

Tín*_*ang 49

使用正则表达式

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

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

ref MDN:Number.prototype.toLocaleString()

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

ref Intl.NumberFormat

在这里演示

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

性能

性能 http://jsben.ch/sifRd


Jav*_*ces 39

这个问题得到的答案数量给我留下了深刻的印象。我喜欢uKolka的回答:

n.toLocaleString()
Run Code Online (Sandbox Code Playgroud)

但不幸的是,在某些语言环境(如西班牙语)中,对于低于 10,000 的数字,它无法按预期工作(恕我直言):

Number(1000).toLocaleString('ES-es')
Run Code Online (Sandbox Code Playgroud)

给与1000不给1.000

请参阅toLocaleString 在所有浏览器中小于 10000 的数字不起作用以了解原因。

所以我不得不使用Elias Zamaria的答案选择正确的千位分隔符:

n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))
Run Code Online (Sandbox Code Playgroud)

对于使用,.作为千位分隔符的两种语言环境,这一个都可以很好地作为单行,并且在所有情况下都从 1,000 开始工作。

Number(1000).toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))
Run Code Online (Sandbox Code Playgroud)

提供1.000西班牙语言环境上下文。

如果您想绝对控制数字的格式化方式,您还可以尝试以下操作:

let number   = 1234.567
let decimals = 2
let decpoint = '.' // Or Number(0.1).toLocaleString().substring(1, 2)
let thousand = ',' // Or Number(10000).toLocaleString().substring(2, 3)

let n = Math.abs(number).toFixed(decimals).split('.')
n[0] = n[0].split('').reverse().map((c, i, a) =>
  i > 0 && i < a.length && i % 3 == 0 ? c + thousand : c
).reverse().join('')
let final = (Math.sign(number) < 0 ? '-' : '') + n.join(decpoint)

console.log(final)
Run Code Online (Sandbox Code Playgroud)

1,234.57

这个不需要正则表达式。它的工作原理是首先将数字调整为所需的小数位数toFixed,然后将其除以小数点(.如果有)。然后将左侧变成一组反转的数字。然后从头开始每三个数字添加一个千位分隔符,结果再次反转。最终的结果是两部分的结合。输入数字的符号Math.abs先用 删除,然后在必要时放回去。

它不是单行的,但时间也不长,而且很容易变成一个函数。为清楚起见,添加了变量,但如果事先知道,这些变量可以替换为它们所需的值。您可以使用表达式toLocaleString来找出小数点的正确字符和当前语言环境的千位分隔符(请记住,这些需要更现代的 Javascript。)


Dus*_*Sun 36

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


J.M*_*ney 32

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

第一个代码段补充说,模仿功能PHPnumber_format()到数字样机.如果我格式化一个数字,我通常需要小数位,所以该函数需要显示小数位数.有些国家使用逗号作为十进制和小数作为千位分隔符,因此该函数允许设置这些分隔符.

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

您将使用如下:

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

我发现我经常需要为数学运算取回数字,但是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));
}
Run Code Online (Sandbox Code Playgroud)

现在您可以使用以下两个函数:

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

  • @ J.Money .toString是不必要的,toFixed已经返回一个字符串. (3认同)
  • 很好,我借用了第一种方法;)但是,当您要使用欧洲格式并且数字是小数时,它不会产生正确的结果。第5行应为:“ var parts = this.toFixed(decimals).toString()。split('。');” (2认同)

use*_*916 22

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

/\B(?=(\d{3})+\b)/g

"123456".replace(/\B(?=(\d{3})+\b)/g, ",")
Run Code Online (Sandbox Code Playgroud)

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

  • 它在小数点后添加: 12.3456".replace(/\B(?=(\d{3})+\b)/g, ",") == 12.3,456 (2认同)

Sin*_*nan 19

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


phe*_*e23 17

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

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

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

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

  • 虽然如果我们可以使用一个简单的内置函数,这将是非常棒的,它有可怕的浏览器实现.例如,IE 8-10和所有Safari都不支持此功能 (2认同)

Dul*_*sta 16

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

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

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

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


Shi*_*hah 13

如果你正在处理货币值和格式化很多,那么可能值得添加处理大量边缘情况和本地化的微小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
Run Code Online (Sandbox Code Playgroud)


run*_*sun 12

以下代码使用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] : ''); 
}
Run Code Online (Sandbox Code Playgroud)

它显示出有前景的表现:http://jsperf.com/number-formatting-with-commas/5

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


MMM*_*ION 12

通用、快速、准确、简单的功能

\n
    \n
  • 使用正则表达式(快速且准确)
  • \n
  • 支持数字(浮点/整数)/字符串/字符串中的多个数字
  • \n
  • 智能井(不对小数进行分组-兼容不同类型的分组)
  • \n
  • 支持所有浏览器,特别是“Safari”和“IE”以及许多旧浏览器
  • \n
  • [可选] 尊重非英语(波斯语/阿拉伯语)数字(+ 前缀)
  • \n
\n
TL;DR - 完整版功能(缩小):
\n

\r\n
\r\n
// num: Number/s (String/Number),\n// sep: Thousands separator (String) - Default: \',\'\n// dec: Decimal separator (String) - Default: \'.\' (Just one char)\n// u: Universal support for languages characters (String - RegEx character set / class) - Example: \'[\\\\d\\\\u0660-\\\\u0669\\\\u06f0-\\\\u06f9]\' (English/Persian/Arabic), Default: \'\\\\d\' (English)\n\nfunction formatNums(num,sep,dec,u){sep=sep||\',\';u=u||\'\\\\d\';if(typeof num!=\'string\'){num=String(num);if(dec&&dec!=\'.\')num=num.replace(\'.\',dec);}return num.replace(RegExp(\'\\\\\'+(dec||\'.\')+u+\'+|\'+u+\'(?=(?:\'+u+\'{3})+(?!\'+u+\'))\',\'g\'),function(a){return a.length==1?a+sep:a})}\n\ntext=\'100000000 English or Persian/Arabic \xdb\xb1\xdb\xb2\xdb\xb3\xdb\xb4\xdb\xb5\xdb\xb6\xdb\xb7\xdb\xb8\xdb\xb9/\xd9\xa0\xd9\xa1\xd9\xa2\xd9\xa3\xd9\xa4\xd9\xa5\xd9\xa6\xd9\xa7\xd9\xa8\xd9\xa9 this is 123123123.123123123 with this -123123 and these 10 100 1000 123123/123123 (2000000) .33333 100.00 or any like 500000Kg\';\n\nconsole.log(formatNums(10000000.0012));\nconsole.log(formatNums(10000000.0012,\'.\',\',\')); // German\nconsole.log(formatNums(text,\',\',\'.\',\'[\\\\d\\\\u0660-\\\\u0669\\\\u06f0-\\\\u06f9]\')); // Respect Persian/Arabic digits
Run Code Online (Sandbox Code Playgroud)\r\n
<input oninput="document.getElementById(\'result\').textContent=formatNums(this.value)" placeholder="Type a number here">\n<div id="result"></div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

为什么对其他答案不满意?

\n
    \n
  • Number.prototype.toLocaleString() / Intl.NumberFormat \n(正确答案)\n
      \n
    • 如果没有很好的论点,我们就不能期望相同的结果。此外,对于参数选项,我们仍然无法确定结果是什么,因为它将使用本地设置,并且可能的客户端修改会对其产生影响,或者浏览器/设备不支持它。
    • \n
    • >~2016 年浏览器支持某些报告,并且在 2021 年仍然支持这些报告​​,这些报告在某些情况下会按预期返回SafariIE/Edge未按预期返回。
    • \n
    • toLocaleString()处理数字,Intl.NumberFormat处理字符串/数字;字符串将被/必须被解析,并且如果需要的话也会被舍入,所以:\n
        \n
      • 如果我们已经有了本地化字符串,则non-English digits必须将数字替换为英文字符串,然后解析它,然后再次将其与本地选项一起使用。(如果它返回我们期望的结果)
      • \n
      • 一般来说,在解析时我们不能期望不missing decimal zeros或细节big numbers或尊重other languages numeral characters
      • \n
      \n
    • \n
    • 十进制/千位分隔符的自定义不能超过语言选项,除非再次使用 Replace() + RegEx 进行后修复。(例如,在波斯语中,我们通常不使用建议的阿拉伯逗号,有时我们也会使用\xe2\x88\x95分数/除法斜杠作为小数分隔符)
    • \n
    • 循环性能缓慢
    • \n
    \n
  • \n
  • 不太好的正则表达式方式(最快和单行方式)\n
      \n
    • /\\B(?=(\\d{3})+\\b)/它也会对小数进行分组。// 123,123.123,123 !!!
    • \n
    • /(?<!\\.\\d+)\\B(?=(\\d{3})+\\b)/使用了后视功能,但还没有得到很好的支持。请检查:
      \n https://caniuse.com/js-regexp-lookbehind
      \n https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#browser_compatibility
      \n注意:一般来说,lookbehind 可能会违背原始的 RegEx 结构(因为分析器应该如何工作,就像不要将原始后置数据作为解析器进行缓冲),实际上它会使性能严重降低(在本例中约为 30%)。我认为随着时间的推移,它是根据要求推入内部的。
    • \n
    • /\\B(?=(?=\\d*\\.)(\\d{3})+(?!\\d))/只使用浮点数并忽略整数。
    • \n
    • .replace(/(?:[^.\\d]|^)\\d+/g,function(a){return a.replace(/\\B(?=(?:\\d{3})+\\b)/g,\',\');}) (我的旧想法)使用 2 个正则表达式。第一个找到整数部分,第二个放置分隔符。为什么可以混合使用 2 个功能?
    • \n
    • /(\\..*)$|(\\d)(?=(\\d{3})+(?!\\d))/g@djulien的好主意- 我投票了)但是当正则表达式是全局的时,(\\..*)$即使末尾有空格,它也可能会出错。
      \n此外,使用捕获组(示例(\\d):)会降低性能,因此如果可能,请使用非捕获组(示例:)(?:\\d)或者如果我们的函数中已存在语句,那么我们将其混合。\n在这种情况下,不使用捕获组可提高性能约 20%,而在vs
      的情况下,第二个速度快约 8%。\n关于正则表达式性能:\n/\\B(?=(\\d{3})+\\b)/g/\\B(?=(?:\\d{3})+\\b)/g
      https://jsben.ch/HUmDA\n注意:不同的方法、浏览器、硬件、系统状态、案例甚至 ECMAScript 的更改都会影响性能检查的结果。但逻辑上的一些变化应该会影响结果,我用这个只是作为视觉示例。
    • \n
    \n
  • \n
  • 使用像Numeral.js 这样的库对于简单任务来说并不是必需的功能。
  • \n
  • 繁重的代码/不准确的函数使用了.split(\'.\')or.toFixed()Math.floor()...
  • \n
\n
\n

最后结果:

\n

没有最好的,应该根据需要选择。我的排序优先顺序;

\n
    \n
  1. 兼容性
  2. \n
  3. 能力
  4. \n
  5. 普遍性
  6. \n
  7. 使用方便
  8. \n
  9. 表现
  10. \n
\n

toLocaleString()(兼容性-通用性)【原生功能】

\n
    \n
  • 如果您必须将数字和分组从英语更改为另一种语言
  • \n
  • 如果您不确定您的客户语言
  • \n
  • 如果您不需要确切的预期结果
  • \n
  • 如果您不关心旧版本的 Safari
  • \n
\n
// 1000000.2301\nparseFloat(num) // (Pre-fix) If the input is string\n    .toLocaleString(\'en-US\', {\n        useGrouping: true // (Default is true, here is just for show)\n    });\n// 1,000,000.23\n
Run Code Online (Sandbox Code Playgroud)\n

阅读更多: https://www.w3schools.com/jsref/jsref_tolocalestring_number.asp

\n

Intl.NumberFormat()(能力-通用性-兼容性)【原生功能】

\n

toLocaleString()几乎与+相同

\n
    \n
  • 支持货币、单位等的强大能力...任何语言(现代浏览器)
  • \n
\n
// 1000000.2301\nnew Intl.NumberFormat(\'en-US\', { // It can be \'fa-IR\' : Farsi - Iran\n    numberingSystem: \'arab\'\n}).format(num)\n// \xd9\xa1\xd9\xac\xd9\xa0\xd9\xa0\xd9\xa0\xd9\xac\xd9\xa0\xd9\xa0\xd9\xa0\xd9\xab\xd9\xa2\xd9\xa3\n
Run Code Online (Sandbox Code Playgroud)\n

了解更多:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat

\n

有了这么多的原生函数选项,我们仍然不能期望:

\n
    \n
  • 确切的结果(+不解析输入/不四舍五入/不转换大数)
  • \n
  • 接受其他语言数字作为输入
  • \n
  • 自定义分隔符
  • \n
  • 信任浏览器支持
  • \n
  • 表现
  • \n
\n

所以你可能需要一个类似以下的函数:

\n

formatNums()(兼容性 - 易于使用)

\n

完整版(功能) (不比 toLocaleString 快) - 解释:

\n
function formatNums(num, sep, dec, u) {\n    // Setting defaults\n    sep = sep || \',\'; // Seperator\n    u = u || \'\\\\d\'; // Universal character set \\d: 0-9 (English)\n    // Mixing of Handeling numbers when the decimal character should be changed + Being sure the input is string\n    if (typeof num != \'string\') {\n        num = String(num);\n        if (dec && dec != \'.\') num = num.replace(\'.\', dec); // Replacing sure decimal character with the custom\n    }\n    //\n    return num.replace(RegExp(\'\\\\\' + (dec || \'.\') + u + \'+|\' + u + \'(?=(?:\' + u + \'{3})+(?!\' + u + \'))\', \'g\'),\n        // The RegEx will be like /\\.\\d+|\\d(?=(?:\\d{3})+(?!\\d))/g if not be customized \n        // RegEx explain:\n        // 1) \\.\\d+  :  First try to get any part that started with a dot and followed by any much of English digits, one or more (For ignoring it later)\n        // 2) |  :  Or\n        // 3) \\d  :  Get any 1 char digit\n        // 3.1) (?=...)  :  That the next of that should be\n        // 3.2) (?:\\d{3})  :  3 length digits\n        // 3.2.1) +  :  One or more of the group\n        // 3.3) (?!\\d)  :  ...till any place that there is no digits\n        function(a) { // Any match can be the decimal part or the integer part so lets check it\n            return a.length == 1 ? a + sep : a // If the match is one character, it is from the grouping part as item (3) in Regex explain so add the seperator next of it, if not, ignore it and return it back.\n        })\n}\n
Run Code Online (Sandbox Code Playgroud)\n

\r\n
\r\n
// 1000000.2301\nparseFloat(num) // (Pre-fix) If the input is string\n    .toLocaleString(\'en-US\', {\n        useGrouping: true // (Default is true, here is just for show)\n    });\n// 1,000,000.23\n
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

使用此处的示例:\n https://jsfiddle.net/PAPIONbit/198xL3te/

\n

轻型版本(性能) (比 toLocaleString 快约 30%)

\n

\r\n
\r\n
// 1000000.2301\nnew Intl.NumberFormat(\'en-US\', { // It can be \'fa-IR\' : Farsi - Iran\n    numberingSystem: \'arab\'\n}).format(num)\n// \xd9\xa1\xd9\xac\xd9\xa0\xd9\xa0\xd9\xa0\xd9\xac\xd9\xa0\xd9\xa0\xd9\xa0\xd9\xab\xd9\xa2\xd9\xa3\n
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

检查正则表达式(没有必要的功能):https ://regexr.com/66ott

\n

(num+\'\').replace(/\\B(?=(?:\\d{3})+\\b)/g,\',\');(性能-兼容性)

\n

如果输入是指定/预定义的,则最好选择。(就像通常的价格一样,小数位数肯定不会超过 3 位)\n (比 toLocaleString 快约 65%)

\n

\r\n
\r\n
function formatNums(num, sep, dec, u) {\n    // Setting defaults\n    sep = sep || \',\'; // Seperator\n    u = u || \'\\\\d\'; // Universal character set \\d: 0-9 (English)\n    // Mixing of Handeling numbers when the decimal character should be changed + Being sure the input is string\n    if (typeof num != \'string\') {\n        num = String(num);\n        if (dec && dec != \'.\') num = num.replace(\'.\', dec); // Replacing sure decimal character with the custom\n    }\n    //\n    return num.replace(RegExp(\'\\\\\' + (dec || \'.\') + u + \'+|\' + u + \'(?=(?:\' + u + \'{3})+(?!\' + u + \'))\', \'g\'),\n        // The RegEx will be like /\\.\\d+|\\d(?=(?:\\d{3})+(?!\\d))/g if not be customized \n        // RegEx explain:\n        // 1) \\.\\d+  :  First try to get any part that started with a dot and followed by any much of English digits, one or more (For ignoring it later)\n        // 2) |  :  Or\n        // 3) \\d  :  Get any 1 char digit\n        // 3.1) (?=...)  :  That the next of that should be\n        // 3.2) (?:\\d{3})  :  3 length digits\n        // 3.2.1) +  :  One or more of the group\n        // 3.3) (?!\\d)  :  ...till any place that there is no digits\n        function(a) { // Any match can be the decimal part or the integer part so lets check it\n            return a.length == 1 ? a + sep : a // If the match is one character, it is from the grouping part as item (3) in Regex explain so add the seperator next of it, if not, ignore it and return it back.\n        })\n}\n
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

+

\n
对于波斯/阿拉伯本地客户:
\n

如果您的客户要像伊朗常用的那样使用波斯语/阿拉伯数字进行输入,我认为最好的方法是不要保留原始字符,而是在处理之前将它们转换为英语,以便您可以计算它。

\n
// \xdb\xb1\xdb\xb2\xdb\xb3\xdb\xb4\xdb\xb5\xdb\xb6\xdb\xb7\xdb\xb8\xdb\xb9\xdb\xb0\nfunction toEnNum(n) { // Replacing Persian/Arabic numbers character with English\n    n.replace(/[\\u0660-\\u0669\\u06f0-\\u06f9]/g, // RegEx unicode range Persian/Arabic numbers char\n        function(c) {\n            return c.charCodeAt(0) & 0xf; // Replace the char with real number by getting the binary index and breaking to lowest using 15\n        }\n    );\n}\n// 1234567890\n
Run Code Online (Sandbox Code Playgroud)\n

为了仍然将它们显示为原始外观,有两种方法:

\n\n
\n

我在这篇文章中的老式函数:(比 toLocalString 快约 15%)

\n
// 10000000.0012\nfunction formatNums(n, s) {\n    return s = s || ",", String(n).\n    replace(/(?:^|[^.\\d])\\d+/g, // First this RegEx take just integer parts\n        function(n) {\n            return n.replace(/\\B(?=(?:\\d{3})+\\b)/g, s);\n        })\n}\n// 10,000,000.0012\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这不是代码高尔夫。我认为使用一些空格和换行符来使代码更具可读性是可以的,即使它们不是严格要求的。 (2认同)

Noa*_*tas 11

这是一个简单的函数,可以为千位分隔符插入逗号.它使用数组函数而不是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('');
};
Run Code Online (Sandbox Code Playgroud)

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

  • 嗨.. 这个例子很棒。但它也会为小数部分添加逗号。只是一个编辑: function formatNumber( num ) { var decimalPart = ''; num = num.toString(); if ( num.indexOf( '.' ) != -1 ) { decimalPart = '.'+ num.split( '.' )[1]; num = parseInt(num.split( '.' )[0]); } var array = num.toString().split(''); 无功指数 = -3; while ( array.length + index &gt; 0 ) { array.splice( index, 0, ',' ); // 递减 4,因为我们刚刚向数组添加了另一个单元。指数 -= 4; } return array.join( '' ) + decimalPart; }; (2认同)

Bat*_*han 10

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

let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
  minimumFractionDigits: 2,
});

// Use it.

formatter.format(amount);
Run Code Online (Sandbox Code Playgroud)

输出:

3,50,256.95
Run Code Online (Sandbox Code Playgroud)


Oli*_*ver 9

您也可以使用Intl.NumberFormat构造函数。这是您的操作方法。

 resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber); 
Run Code Online (Sandbox Code Playgroud)


Lon*_*est 9

我的答案是唯一一个用更明智的替代方案完全取代 jQuery 的答案:

function $(dollarAmount)
{
    const locale = 'en-US';
    const options = { style: 'currency', currency: 'USD' };
    return Intl.NumberFormat(locale, options).format(dollarAmount);
}
Run Code Online (Sandbox Code Playgroud)

此解决方案不仅添加逗号,而且如果您输入的金额类似于$(1000.9999)您将获得 1,001.00 美元,它还会四舍五入到最接近的便士。此外,您输入的值可以安全地是数字或字符串;没关系。

如果您正在处理金钱,但不想在金额上显示前导美元符号,您还可以添加此函数,该函数使用前一个函数但删除了$

function no$(dollarAmount)
{
    return $(dollarAmount).replace('$','');
}
Run Code Online (Sandbox Code Playgroud)

如果您处理金钱,并且有不同的十进制格式要求,这里有一个更通用的函数:

function addCommas(number, minDecimalPlaces = 0, maxDecimalPlaces = Math.max(3,minDecimalPlaces))
{
    const options = {};
    options.maximumFractionDigits = maxDecimalPlaces;
    options.minimumFractionDigits = minDecimalPlaces;
    return Intl.NumberFormat('en-US',options).format(number);
}
Run Code Online (Sandbox Code Playgroud)

哦,顺便说一句,这段代码在某些旧版本的 Internet Explorer 中不起作用的事实完全是故意的。我会随时尝试破解 IE,只要我发现它不支持现代标准。

请记住,评论部分中的过度赞美被认为是题外话。相反,只需给我投票。

  • Number(n).toLocaleString() 似乎是最好的答案,但如果所有用户想要的是他们的号码中的逗号。 (2认同)

Ice*_*ank 8

var number = 2561556862056.12;

console.log(new Intl.NumberFormat().format(number));
Run Code Online (Sandbox Code Playgroud)

这是我找到的最简单的方法


Pik*_*er2 8

这是一个简单的可重用函数,它返回具有指定小数位数的字符串,并允许您切换是否包含逗号。

function format_number(number, num_decimals, include_comma)
{
    return number.toLocaleString('en-US', {useGrouping: include_comma, minimumFractionDigits: num_decimals, maximumFractionDigits: num_decimals});
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

format_number(1234.56789, 2, true); // Returns '1,234.57'
format_number(9001.42, 0, false); // Returns '9001'
Run Code Online (Sandbox Code Playgroud)

如果您需要进一步自定义字符串,可以在此处找到格式选项列表。


Ron*_*rby 7

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

$(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' ) );
  
  
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="theDudeAbides"></div>
Run Code Online (Sandbox Code Playgroud)


Fel*_*oni 6

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

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.floor(Math.abs(number)).toString()

        , i     = n.length % 3 
        , f     = ((number < 0) ? '-' : '') + n.substr(0, i)
    ;

    for(;i<n.length;i+=3) {
        if(i!=0) f+=ts;
        f+=n.substr(i,3);
    }

    if(dp > 0) 
        f += ds + parseFloat(number).toFixed(dp).split('.')[1]

    return f;
}
Run Code Online (Sandbox Code Playgroud)

@Jignesh Sanghani 的一些更正,不要忘记支持他的评论。

  • `fn.substr(0, i)` 替换为 `n.substr(0, i)`,`number.toFixed(dp).split('.')[1]` 替换为 `parseFloat(number)。 toFixed(dp).split('.')[1]`。因为当我直接使用时它会给我一个错误。请更新您的代码 (3认同)

小智 6

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

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

捷径

1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})
Run Code Online (Sandbox Code Playgroud)


Igo*_*kov 6

仅适用于未来的 Google 员工(或不一定是“Google 员工”):

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

所以,是的,您可能会使用一些建议的选项,甚至编写一些原始但有用的东西,例如:

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

此处使用的正则表达式相当简单,循环将精确执行完成工作所需的次数。

你可能会更好地优化它,“DRYify”代码等等。

然而,

(-1234567.0987).toLocaleString();
Run Code Online (Sandbox Code Playgroud)

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

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

在您想向用户显示结果数字的情况下, .toLocaleString() 方法使您能够与您的网站或应用程序的用户(无论她/他的语言是什么)说同一种语言。

根据 ECMAScript 文档,这种方法是在 1999 年引入的,我相信这样做的原因是希望互联网在某个时候将世界各地的人们连接起来,因此,需要一些“内化”工具。

今天,互联网确实将我们所有人联系在一起,因此,重要的是要记住,世界比我们想象的要复杂得多,而且(/几乎)我们所有人都在这里,在互联网中。

显然,考虑到人的多样性,不可能保证每个人都拥有完美的 UX,因为我们说不同的语言,重视不同的事物等等。正因为如此,尽可能地尝试将事物本地化就显得尤为重要.

因此,考虑到日期、时间、数字等的表示有一些特定的标准,并且我们有一个工具可以以最终用户喜欢的格式显示这些内容,这并不罕见,而且几乎是不负责任的使用那个工具(特别是在我们想要向用户显示这些数据的情况下)?

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

new Date();
Run Code Online (Sandbox Code Playgroud)

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


jas*_*p85 5

我认为你的解决方案是我见过的较短的解决方案之一。我不认为有任何标准的 JavaScript 函数可以完成这类事情,所以你可能只能靠自己了。

我检查了 CSS 3 规范,看看是否可以在 CSS 中执行此操作,但除非您希望每个数字都有自己的<span>,否则我认为这是不可能的。

我确实在Google Code上发现了一个看起来很有前途的项目:flexible-js-formatting。我没有使用过它,但它看起来非常灵活,并且使用JsUnit进行单元测试。开发人员还有很多关于此主题的帖子(尽管很旧)。

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


Abh*_*jan 5

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

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


Way*_*ett 5

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

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

一些例子:

format(77.03453, 2); // "77.03"
format(78436589374); // "78,436,589,374"
format(784, 4);      // "784.0000"
format(-123456);     // "-123,456"
Run Code Online (Sandbox Code Playgroud)


Bed*_*ges 5

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

使用Numeral.js.

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

只有当浏览器兼容性不是问题时,才应使用Number.prototype.toLocaleString().


Kir*_*eas 5

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

编辑:该功能仅适用于正数。例如:

var number = -123123231232;
formatNumber(number)
Run Code Online (Sandbox Code Playgroud)

输出:“ 123,123,231,232”

但是回答以上toLocaleString()方法的问题只能解决问题。

var number = 123123231232;
    number.toLocaleString()
Run Code Online (Sandbox Code Playgroud)

输出:“ 123,123,231,232”

欢呼!


小智 5

对于任何人谁喜欢1船和一个正则表达式,但希望使用分裂(),这里是从其他答案,处理(忽略)小数位的正则表达式的增强版本:

    var formatted = (x+'').replace(/(\..*)$|(\d)(?=(\d{3})+(?!\d))/g, (digit, fract) => fract || digit + ',');
Run Code Online (Sandbox Code Playgroud)

正则表达式首先匹配以文字“.”开头的子字符串。并将其替换为自身(“fract”),然后匹配任何数字,后跟 3 位数字的倍数,并在其后加上“,”。

例如,x = 12345678.12345678 将给出formatted = '12,345,678.12345678'。


Rob*_*bok 5

如果您正在寻找一个简短而甜蜜的解决方案:

const number = 12345678.99;

const numberString = String(number).replace(
    /^\d+/,
    number => [...number].map(
        (digit, index, digits) => (
            !index || (digits.length - index) % 3 ? '' : ','
        ) + digit
    ).join('')
);

// numberString: 12,345,678.99
Run Code Online (Sandbox Code Playgroud)