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

我是这样做的:

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

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


当前回答

我的“真正”正则表达式唯一的解决方案

你看到上面那些热情的球员了吗?也许你可以打高尔夫球,这是我的击球。

n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " ").replace(/(?<=\.(\d{3})+)\B/g, " ")

使用 如国际单位制在其出版物《国际单位制手册:国际单位制(SI)》(见§5.3.4.)第八版(2006年)中所说,千位分隔符的空格(U+2009)。第九版(2019年)建议使用空格(见§5.4.4.)。你可以使用任何你想要的东西,包括逗号。


See.

const integer_part_only=n=>`${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\B)/g,“I”);const fractional_part_only=n=>`${n}`替换(/(?<=\.(\d{3})+)\B/g,“F”);const both=n=>仅分数部分(整数部分(n));功能演示(编号){//我正在使用Chrome 74。console.log(`${number}→ “${integer_part_only(number)}”(仅整数部分)→ “${fractional_part_only(数字)}”(仅分数部分)→ “${both(number)}”(both)`);}演示(Math.random()*10e5);演示(123456789.01234567);演示(123456789);演示(0.0123456789);


它是如何工作的?

对于整数部分

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

.替换(……,“I”)放入“I”/……/克\B两个相邻数字之间(?=……)右侧部分为(\d{3})+一个或多个三位数块\b后跟非数字,例如句点、字符串结尾等,(?<!……)负外观,不包括其左侧部分\.\d+是一个后跟数字的点(“有一个小数分隔符”)。

对于小数部分

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

.替换(……,“F”)放入“F”/……/克\B两个相邻数字之间(?<=……)左半部分为\. 十进制分隔符(\d{3})+后跟一个或多个三位数块。


字符类和边界

\d)匹配任何数字(阿拉伯数字)。相当于[0-9]。例如/\d/或/[0-9]/匹配B2中的2是组号。\b级匹配单词边界。这是一个单词字符后面或前面没有其他单词字符的位置,例如在字母和空格之间。注意,匹配中不包括匹配的单词边界。换句话说,匹配单词边界的长度为零。示例:/\bm/匹配月亮中的m;/oo\b/与moon中的oo不匹配,因为oo后面跟着n,n是一个单词字符;/oon \b/匹配moon中的oon,因为oon是字符串的结尾,因此后面不跟单词字符;/\w\b/w/将永远不会匹配任何内容,因为单词字符后面永远不能同时跟有非单词和单词字符。\B级匹配非单词边界。这是上一个字符和下一个字符类型相同的位置:要么两者都必须是单词,要么两者都是非单词。例如两个字母之间或两个空格之间。字符串的开头和结尾被视为非单词。与匹配的单词边界相同,匹配的非单词边界也不包括在匹配中。例如/\中午开始比赛;/你昨天可能和你比赛。


浏览器兼容性

https://caniuse.com/#feat=js-正则表达式查找

其他回答

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

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

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

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"

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

我的“真正”正则表达式唯一的解决方案

你看到上面那些热情的球员了吗?也许你可以打高尔夫球,这是我的击球。

n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " ").replace(/(?<=\.(\d{3})+)\B/g, " ")

使用 如国际单位制在其出版物《国际单位制手册:国际单位制(SI)》(见§5.3.4.)第八版(2006年)中所说,千位分隔符的空格(U+2009)。第九版(2019年)建议使用空格(见§5.4.4.)。你可以使用任何你想要的东西,包括逗号。


See.

const integer_part_only=n=>`${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\B)/g,“I”);const fractional_part_only=n=>`${n}`替换(/(?<=\.(\d{3})+)\B/g,“F”);const both=n=>仅分数部分(整数部分(n));功能演示(编号){//我正在使用Chrome 74。console.log(`${number}→ “${integer_part_only(number)}”(仅整数部分)→ “${fractional_part_only(数字)}”(仅分数部分)→ “${both(number)}”(both)`);}演示(Math.random()*10e5);演示(123456789.01234567);演示(123456789);演示(0.0123456789);


它是如何工作的?

对于整数部分

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

.替换(……,“I”)放入“I”/……/克\B两个相邻数字之间(?=……)右侧部分为(\d{3})+一个或多个三位数块\b后跟非数字,例如句点、字符串结尾等,(?<!……)负外观,不包括其左侧部分\.\d+是一个后跟数字的点(“有一个小数分隔符”)。

对于小数部分

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

.替换(……,“F”)放入“F”/……/克\B两个相邻数字之间(?<=……)左半部分为\. 十进制分隔符(\d{3})+后跟一个或多个三位数块。


字符类和边界

\d)匹配任何数字(阿拉伯数字)。相当于[0-9]。例如/\d/或/[0-9]/匹配B2中的2是组号。\b级匹配单词边界。这是一个单词字符后面或前面没有其他单词字符的位置,例如在字母和空格之间。注意,匹配中不包括匹配的单词边界。换句话说,匹配单词边界的长度为零。示例:/\bm/匹配月亮中的m;/oo\b/与moon中的oo不匹配,因为oo后面跟着n,n是一个单词字符;/oon \b/匹配moon中的oon,因为oon是字符串的结尾,因此后面不跟单词字符;/\w\b/w/将永远不会匹配任何内容,因为单词字符后面永远不能同时跟有非单词和单词字符。\B级匹配非单词边界。这是上一个字符和下一个字符类型相同的位置:要么两者都必须是单词,要么两者都是非单词。例如两个字母之间或两个空格之间。字符串的开头和结尾被视为非单词。与匹配的单词边界相同,匹配的非单词边界也不包括在匹配中。例如/\中午开始比赛;/你昨天可能和你比赛。


浏览器兼容性

https://caniuse.com/#feat=js-正则表达式查找

如果所有浏览器(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));