Javascript 添加逗号或空格以将每三个数字分组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6784894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:10:29  来源:igfitidea点击:

Add commas or spaces to group every three digits

javascriptstring-formatting

提问by Sophie Alpert

I have a function to add commas to numbers:

我有一个为数字添加逗号的函数:

function commafy( num ) {
  num.toString().replace( /\B(?=(?:\d{3})+)$/g, "," );
}

Unfortunately, it doesn't like decimals very well. Given the following usage examples, what is the best way to extend my function?

不幸的是,它不太喜欢小数。鉴于以下使用示例,扩展我的功能的最佳方法是什么?

commafy( "123" )                 // "123"
commafy( "1234" )                // "1234"
                                 // Don't add commas until 5 integer digits
commafy( "12345" )               // "12,345"
commafy( "1234567" )             // "1,234,567"
commafy( "12345.2" )             // "12,345.2"
commafy( "12345.6789" )          // "12,345.6789"
                                 // Again, nothing until 5
commafy( ".123456" )             // ".123 456"
                                 // Group with spaces (no leading digit)
commafy( "12345.6789012345678" ) // "12,345.678 901 234 567 8"

Presumably the easiest way is to first split on the decimal point (if there is one). Where best to go from there?

想必最简单的方法是先在小数点上拆分(如果有的话)。从那里最好去哪里?

回答by Ghostoy

Just split into two parts with '.' and format them individually.

只需用'.'分成两部分 并单独格式化它们。

function commafy( num ) {
    var str = num.toString().split('.');
    if (str[0].length >= 5) {
        str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, ',');
    }
    if (str[1] && str[1].length >= 5) {
        str[1] = str[1].replace(/(\d{3})/g, ' ');
    }
    return str.join('.');
}

回答by Itay Merchav

Simple as that:

就那么简单:

var theNumber = 3500;
theNumber.toLocaleString();

回答by TommyWhite

Here are two concise ways I think maybe useful:

以下是我认为可能有用的两种简洁方法:

  1. Number.prototype.toLocaleString
  1. Number.prototype.toLocaleString

This method can convert a numberto a string with a language-sensitive representation. It allows two parameters, which is locales& options. Those parameters may be a bit confusing, for more detail see that doc from MDN above.

此方法可以将数字转换为具有语言敏感表示的字符串。它允许两个参数,即locales& options。这些参数可能有点令人困惑,有关更多详细信息,请参阅上面来自 MDN 的文档。

In a word, you could simply use is as below:

总之,你可以简单地使用如下:

console.log(
   Number(1234567890.12).toLocaleString()
)
// log -> "1,234,567,890.12"

If you see different with me that because we ignore both two parameters and it will return a string base on your operation system.

如果您看到我的不同之处,因为我们忽略了两个参数,它将根据您的操作系统返回一个字符串。

  1. Use regex to match a string then replace to a new string.

    Why we consider this? The toLocaleString()is a bit confusing and not all browser supported, also toLocaleString()will round the decimal, so we can do it in another way.

  1. 使用正则表达式匹配一个字符串,然后替换为一个新字符串。

    我们为什么考虑这个?这toLocaleString()有点令人困惑,并非所有浏览器都支持,toLocaleString()也会四舍五入,所以我们可以用另一种方式来做。

// The steps we follow are:
// 1. Converts a number(integer) to a string.
// 2. Reverses the string.
// 3. Replace the reversed string to a new string with the Regex
// 4. Reverses the new string to get what we want.

// This method is use to reverse a string.
function reverseString(str) { 
    return str.split("").reverse().join("");  
}

/**
 * @param {string | number} 
 */
function groupDigital(num) {
  const emptyStr = '';
  const group_regex = /\d{3}/g;

  // delete extra comma by regex replace.
  const trimComma = str => str.replace(/^[,]+|[,]+$/g, emptyStr)


  const str = num + emptyStr;
  const [integer, decimal] = str.split('.')

  const conversed = reverseString(integer);

  const grouped = trimComma(reverseString(
    conversed.replace(/\d{3}/g, match => `${match},`)
  ));

  return !decimal ? grouped : `${grouped}.${decimal}`;
}


console.log(groupDigital(1234567890.1234)) // 1,234,567,890.1234
console.log(groupDigital(123456))  // 123,456
console.log(groupDigital("12.000000001"))  // 12.000000001

回答by Alexander Solovey

Easiest way:

最简单的方法:

1

1

var num = 1234567890,
result = num.toLocaleString() ;// result will equal to "1 234 567 890"

2

2

var num = 1234567.890,
result = num.toLocaleString() + num.toString().slice(num.toString().indexOf('.')) // will equal to 1 234 567.890

3

3

var num = 1234567.890123,
result = Number(num.toFixed(0)).toLocaleString() + '.' + Number(num.toString().slice(num.toString().indexOf('.')+1)).toLocaleString()
//will equal to 1 234 567.890 123

4

4

If you want ',' instead of ' ':

如果你想要 ',' 而不是 ' ':

var num = 1234567.890123,
result = Number(num.toFixed(0)).toLocaleString().split(/\s/).join(',') + '.' + Number(num.toString().slice(num.toString().indexOf('.')+1)).toLocaleString()
//will equal to 1,234,567.890 123

If not working, set the parameter like: "toLocaleString('ru-RU')" parameter "en-EN", will split number by the ',' instead of ' '

如果不起作用,请设置参数如:“toLocaleString('ru-RU')”参数“en-EN”,将按','而不是''分割数字

All function used in my code are native JS functions. You'll find them in GOOGLE or in any JS Tutorial/Book

我的代码中使用的所有函数都是原生 JS 函数。您可以在 GOOGLE 或任何 JS 教程/书籍中找到它们

回答by RobG

If you are happy with the integer part (I haven't looked at it closly), then:

如果您对整数部分感到满意​​(我没有仔细看过它),那么:

function formatDecimal(n) {
  n = n.split('.');
  return commafy(n[0]) + '.' + n[1];
}

Of course you may want to do some testing of nfirst to make sure it's ok, but that's the logic of it.

当然,您可能想先对n进行一些测试以确保它没问题,但这就是它的逻辑。

Edit

编辑

Ooops! missed the bit about spaces! You can use the same regular exprssion as commafy except with spaces instead of commas, then reverse the result.

哎呀!错过了关于空间的一点!您可以使用与commafy 相同的正则表达式,但使用空格而不是逗号,然后反转结果。

Here's a function based on vol7ron's and not using reverse:

这是一个基于 vol7ron 且不使用反向的函数:

function formatNum(n) {
  var n = ('' + n).split('.');
  var num = n[0];
  var dec = n[1];
  var r, s, t;

  if (num.length > 3) {
    s = num.length % 3;

    if (s) {
      t = num.substring(0,s);
      num = t + num.substring(s).replace(/(\d{3})/g, ",");
    } else {
      num = num.substring(s).replace(/(\d{3})/g, ",").substring(1);
    }
  }

  if (dec && dec.length > 3) {
    dec = dec.replace(/(\d{3})/g, " ");
  }

  return num + (dec? '.' + dec : '');
}

回答by vol7ron

Here you go edited after reading your comments.

在这里,您在阅读您的评论后进行编辑。

function commafy( arg ) {
   arg += '';                                         // stringify
   var num = arg.split('.');                          // incase decimals
   if (typeof num[0] !== 'undefined'){
      var int = num[0];                               // integer part
      if (int.length > 4){
         int     = int.split('').reverse().join('');  // reverse
         int     = int.replace(/(\d{3})/g, ",");    // add commas
         int     = int.split('').reverse().join('');  // unreverse
      }
   }
   if (typeof num[1] !== 'undefined'){
      var dec = num[1];                               // float part
      if (dec.length > 4){
         dec     = dec.replace(/(\d{3})/g, " ");    // add spaces
      }
   }

   return (typeof num[0] !== 'undefined'?int:'') 
        + (typeof num[1] !== 'undefined'?'.'+dec:'');
}

回答by CLaFarge

This worked for me:

这对我有用:

function commafy(inVal){
   var arrWhole = inVal.split(".");
   var arrTheNumber = arrWhole[0].split("").reverse();
   var newNum = Array();
   for(var i=0; i<arrTheNumber.length; i++){
          newNum[newNum.length] = ((i%3===2) && (i<arrTheNumber.length-1)) ? "," + arrTheNumber[i]: arrTheNumber[i];
   }
   var returnNum = newNum.reverse().join("");
   if(arrWhole[1]){
          returnNum += "." + arrWhole[1];
   }
   return returnNum;
}

回答by HGMamaci

I have extended #RobG's answer a bit more and made a sample jsfiddle

我已经扩展了#RobG 的答案,并制作了一个示例jsfiddle

function formatNum(n, prec, currSign) {
    if(prec==null) prec=2;
  var n = ('' + parseFloat(n).toFixed(prec).toString()).split('.');
  var num = n[0];
  var dec = n[1];
  var r, s, t;

  if (num.length > 3) {
    s = num.length % 3;

    if (s) {
      t = num.substring(0,s);
      num = t + num.substring(s).replace(/(\d{3})/g, ",");
    } else {
      num = num.substring(s).replace(/(\d{3})/g, ",").substring(1);
    }
  }
    return (currSign == null ? "": currSign +" ") + num + (dec? '.' + dec : '');
}
alert(formatNum(123545.3434));
alert(formatNum(123545.3434,2));
alert(formatNum(123545.3434,2,''));

and extended same way the #Ghostoy's answer

并以相同的方式扩展#Ghostoy的答案

function commafy( num, prec, currSign ) {
    if(prec==null) prec=2;
    var str = parseFloat(num).toFixed(prec).toString().split('.');
    if (str[0].length >= 5) {
        str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, ',');
    }
    if (str[1] && str[1].length >= 5) {
        str[1] = str[1].replace(/(\d{3})/g, ' ');
    }
    return (currSign == null ? "": currSign +" ") + str.join('.');
}

alert(commafy(123545.3434));

回答by Dan Witkowski

Assuming your usage examples are not representative of already-working code but instead desired behavior, and you are looking for help with the algorithm, I think you are already on the right track with splitting on any decimals.

假设您的使用示例不代表已经可以运行的代码,而是代表所需的行为,并且您正在寻找算法方面的帮助,我认为您已经走上了正确的轨道,可以拆分任何小数。

Once split, apply the existing regex to the left side, a similiar regex adding the spaces instead of commas to the right, and then rejoin the the two into a single string before returning.

拆分后,将现有的正则表达式应用于左侧,类似的正则表达式在右侧添加空格而不是逗号,然后在返回之前将两者重新连接成一个字符串。

Unless, of course, there are other considerations or I have misunderstood your question.

当然,除非有其他考虑或我误解了您的问题。