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

我是这样做的:

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

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


当前回答

我在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

其他回答

对于任何喜欢1行和单个正则表达式,但不想使用split()的人,这里有一个来自其他答案的正则表达式的增强版本,它处理(忽略)小数点:

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

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

例如,x=12345678.12345678将给出formated=“12345678.12345 678”。

我对这个问题的答案数量印象深刻。我喜欢uKolka的回答:

n.toLocaleString()

但不幸的是,在西班牙语等一些地区,它并不能像预期的那样工作(IMHO):

Number(1000).toLocaleString('ES-es')

给出1000而不是1.000。

请参阅所有浏览器中不能处理小于10000的数字的LocaleString,了解原因。

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

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

对于使用或的两个语言环境,这一行程序都可以很好地作为一行程序使用。在所有情况下,从1000开始工作。

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

给出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)

给出1234.57。

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

它不是一个线性函数,但长度不长,很容易转化为函数。为了清楚起见,添加了变量,但如果事先知道,可以用它们的期望值替换这些变量。您可以使用使用toLocaleString的表达式来查找当前区域设置的小数点和千位分隔符的正确字符(请记住,这些字符需要更现代的Javascript)

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

示例:数字格式化程序(1234567890.123456)=>1234567890数字格式化程序(1234567890.123456,4)=>1234567890.1235numberFormatter(1234567890.123456,4,'.',',')=>1.234.567.8901235欧洲

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

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,则只需返回它。

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

function number_format(number, decimals, dec_point, thousands_sep) {
    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);
}

2014年2月13日更新

人们一直在报告这并不像预期的那样奏效,所以我做了一个包含自动化测试的JSFiddle。

更新日期:2017年11月26日

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

函数number_format(数字,小数,小数点,千位整){变量n=!是有限的(+数字)?0:+数字,prec=!是有限的(+小数)?0:数学abs(小数),sep=(typeof thousands_sep===“undefined”)?“,”:千分之一秒,dec=(dec_point类型==“未定义”)?“.”:dec_点,toFixedFix=函数(n,prec){//修复IE parseFloat(0.55).toFixed(0)=0;var k=数学功率(10,prec);return数学舍入(n*k)/k;},s=(prec?toFixedFix(n,prec):数学舍入(n)).toString().split('.');如果(s[0]。长度>3){s[0]=s[0]。替换(/\B(?=(?:\d{3})+(?!\d))/g,sep);}if((s[1]||'').length<prec){s[1]=s[1]| |“”;s[1]+=新数组(prec-s[1].length+1).join('0');}return s.join(十二月);}var exampleNumber=1;函数测试(预期,数字,小数,小数点,千分位){var actual=number_format(数字,小数,小数点,千位整);控制台日志('测试用例'+exampleNumber+':'+'(小数:'+(小数类型=='未定义'?'(默认)':小数)+',dec_point:“'+(dec_point类型=='未定义'?'(默认)':dec_point)+'”'+',thousands_sep:“'+(类型的thousands-sep==='未定义'?'(默认值)':thousand_sep)+'”)');console.log('=>'+(实际==预期?'通过':'失败')+',得到“'+实际+'”,预期“'+预期+'”。');示例编号++;}测试('1235',1234.56);测试('1234,56',1234.56,2,',','');测试('1234.57',1234.5678,2,'.','');测试('67,00',67,2,',','.');测试(“1000”,1000);测试(‘67.31’,67.311,2);试验(‘1000.6’,1000.55,1);测试('67.00000000',67000,5,',','.');测试('1',0.9,0);试验(‘1.20’,‘1.20‘,2);测试(‘12000’,‘1.20’,4);测试('1.200','1.2000',3);.作为控制台包装{最大高度:100%!重要的}

如果所有浏览器(Safari)都提供Number.protype.toLocaleString(),那么它将非常棒。

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

var putThousandsSeparators;putThousandsSeparators=函数(值,sep){如果(sep==null){sep=',';}//检查是否需要格式化if(value.toString()==value.toLocaleString()){//分裂小数var parts=value.toString().split('.')//格式化整数parts[0]=parts[0]。替换(/\B(?=(\d{3})+(?!\d))/g,sep);//把它们放回一起值=部件[1]?parts.join('.'):parts[0];}其他{value=value.toLocaleString();}返回值;};警报(putThousandsSeparators(1234567.890));