我试图在JavaScript中打印一个整数,用逗号作为千位分隔符。例如,我想将数字1234567显示为“1234567”。我该怎么做?

我是这样做的:

函数编号WithCommas(x){x=x.toString();var模式=/(-?\d+)(\d{3})/;while(模式测试(x))x=x.replace(模式,“$1,$2”);返回x;}console.log(数字与逗号(1000))

有没有更简单或更优雅的方法?如果它也可以与浮点运算一起使用,那就很好了,但这不是必须的。它不需要特定于区域设置来决定句点和逗号。


当前回答

下面是两个不同的浏览器API,它们可以将数字转换为结构化字符串。请记住,并非所有用户的计算机都具有在数字中使用逗号的区域设置。要在输出中强制使用逗号,可以使用任何“西部”语言环境,例如en-US

let number = 1234567890; // Example number to be converted

⚠️ 注意javascript的最大整数值为9007199254740991


到LocaleString

// default behaviour on a machine with a local that uses commas for numbers
let number = 1234567890;
number.toLocaleString(); // "1,234,567,890"

// With custom settings, forcing a "US" locale to guarantee commas in output
let number2 = 1234.56789; // floating point example
number2.toLocaleString('en-US', {maximumFractionDigits:2}); // "1,234.57"

//You can also force a minimum of 2 trailing digits
let number3 = 1.5;
number3.toLocaleString('en-US', {minimumFractionDigits:2, maximumFractionDigits:2}); //"1.50"

数字格式

let number = 1234567890;
let nf = new Intl.NumberFormat('en-US');
nf.format(number); // "1,234,567,890"

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

⚡ 现场演示:https://codepen.io/vsync/pen/MWjdbgL?editors=1000

其他回答

我使用了克里的答案中的想法,但简化了它,因为我只是在为我的特定目的寻找简单的东西。以下是我所拥有的:

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

函数编号WithCommas(x){return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g,“,”);}功能测试(x,预期){常量结果=带逗号的数字(x);常量pass=result==预期;console.log(`${pass?”✓“:”错误===>“}${x}=>${result}`);回传;}让失败=0;失败+=!测试(0,“0”);失败+=!测试(100,“100”);失败+=!测试(1000,“1000”);失败+=!测试(10000,“10000”);失败+=!测试(100000,“100000”);失败+=!测试(1000000,“1000000”);失败+=!测试(10000000,“10000000”);if(失败){console.log(“${failures}测试失败”);}其他{console.log(“所有测试均通过”);}.作为控制台包装{最大高度:100%!重要的}


正则表达式使用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(".");
}

函数编号WithCommas(x){var parts=x.toString().split(“.”);parts[0]=parts[0]。替换(/\B(?=(\d{3})+(?!\d))/g,“,”);return parts.join(“.”);}功能测试(x,预期){常量结果=带逗号的数字(x);常量pass=result==预期;console.log(`${pass?”✓“:”错误===>“}${x}=>${result}`);回传;}让失败=0;失败+=!测试(0,“0”);失败+=!测试(0.123456,“0.123456”);失败+=!测试(100,“100”);失败+=!测试(100.123456,“100.123456”);失败+=!测试(1000,“1000”);失败+=!测试(1000-123456,“1000-123456”);失败+=!测试(10000,“10000”);失败+=!测试(10000.123456,“10000.123454”);失败+=!测试(100000,“100000”);失败+=!测试(100000.123456,“10000.123456”);失败+=!测试(1000000,“1000000”);失败+=!测试(1000000123456,“1000000123446”);失败+=!测试(10000000,“10000000”);失败+=!测试(10000000.123456,“10000000.123454”);if(失败){console.log(“${failures}测试失败”);}其他{console.log(“所有测试均通过”);}.作为控制台包装{最大高度:100%!重要的}

@t.j.crowder指出,现在JavaScript有了lookbacking(支持信息),它可以在正则表达式本身中解决:

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

函数编号WithCommas(x){return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g,“,”);}功能测试(x,预期){常量结果=带逗号的数字(x);常量pass=result==预期;console.log(`${pass?”✓“:”错误===>“}${x}=>${result}`);回传;}让失败=0;失败+=!测试(0,“0”);失败+=!测试(0.123456,“0.123456”);失败+=!测试(100,“100”);失败+=!测试(100.123456,“100.123456”);失败+=!测试(1000,“1000”);失败+=!测试(1000-123456,“1000-123456”);失败+=!测试(10000,“10000”);失败+=!测试(10000.123456,“10000.123454”);失败+=!测试(100000,“100000”);失败+=!测试(100000.123456,“10000.123456”);失败+=!测试(1000000,“1000000”);失败+=!测试(1000000123456,“1000000123446”);失败+=!测试(10000000,“10000000”);失败+=!测试(10000000.123456,“10000000.123454”);if(失败){console.log(“${failures}测试失败”);}其他{console.log(“所有测试均通过”);}.作为控制台包装{最大高度:100%!重要的}

(?<!\.\d*)是一个表示匹配前面不能有。后跟零个或多个数字。至少在V8中,反向查找比拆分和连接解决方案(比较)更快。

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

我在Aki143S的解决方案中添加了tofixed。此解决方案使用点表示千位分隔符,使用逗号表示精度。

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

与@elias zamaria和@t.j.crowder相关

Safari浏览器的负面外观是不能使用<。所以,应该是(?!\.\d*)

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

它适用于Safari和Firefox

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

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

此解决方案不仅添加了逗号,而且在您输入金额如$(1000.9999)时,它还舍入到最接近的一分钱,您将获得1001.00美元。此外,您输入的值可以是数字或字符串;没关系。

如果您正在处理货币,但不希望金额上显示前导美元符号,您也可以添加此函数,该函数使用前一个函数,但删除$:

function no$(dollarAmount)
{
    return $(dollarAmount).replace('$','');
}

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

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

哦,顺便说一句,这段代码在某些旧版本的Internet Explorer中不起作用完全是故意的。我试图随时打破IE,因为它不支持现代标准。

请记住,在评论部分过分的赞扬被认为是离题的。相反,你只要给我一大堆选票。