添加逗号或空格以每三位数字分组

发布于 2024-11-25 10:39:46 字数 873 浏览 0 评论 0原文

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

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

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

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"

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

顾铮苏瑾 2024-12-02 10:39:46

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

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

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, '$1,');
    }
    if (str[1] && str[1].length >= 5) {
        str[1] = str[1].replace(/(\d{3})/g, '$1 ');
    }
    return str.join('.');
}
春风十里 2024-12-02 10:39:46

就这么简单:

var theNumber = 3500;
theNumber.toLocaleString();

Simple as that:

var theNumber = 3500;
theNumber.toLocaleString();
凑诗 2024-12-02 10:39:46

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

  1. Number .prototype.toLocaleString

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

总之,您可以简单地使用如下所示:

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

如果您认为与我不同,因为我们忽略了这两个参数,它将返回基于您的操作系统的字符串。

  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

Here are two concise ways I think maybe useful:

  1. Number.prototype.toLocaleString

This method can convert a number to 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.

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.

// 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

国产ˉ祖宗 2024-12-02 10:39:46

最简单的方法:

1

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

2

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

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

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

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

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

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

Easiest way:

1

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

2

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

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

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 ' '

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

北陌 2024-12-02 10:39:46

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

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

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

编辑

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

这是一个基于 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, ",$1");
    } else {
      num = num.substring(s).replace(/(\d{3})/g, ",$1").substring(1);
    }
  }

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

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

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 n first to make sure it's ok, but that's the logic of it.

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.

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

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, ",$1");
    } else {
      num = num.substring(s).replace(/(\d{3})/g, ",$1").substring(1);
    }
  }

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

  return num + (dec? '.' + dec : '');
}
虫児飞 2024-12-02 10:39:46

我进一步扩展了#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, ",$1");
    } else {
      num = num.substring(s).replace(/(\d{3})/g, ",$1").substring(1);
    }
  }
    return (currSign == null ? "": currSign +" ") + num + (dec? '.' + dec : '');
}
alert(formatNum(123545.3434));
alert(formatNum(123545.3434,2));
alert(formatNum(123545.3434,2,'€'));

并以与#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, '$1,');
    }
    if (str[1] && str[1].length >= 5) {
        str[1] = str[1].replace(/(\d{3})/g, '$1 ');
    }
    return (currSign == null ? "": currSign +" ") + str.join('.');
}

alert(commafy(123545.3434));

I have extended #RobG's answer a bit more and made a sample 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, ",$1");
    } else {
      num = num.substring(s).replace(/(\d{3})/g, ",$1").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

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, '$1,');
    }
    if (str[1] && str[1].length >= 5) {
        str[1] = str[1].replace(/(\d{3})/g, '$1 ');
    }
    return (currSign == null ? "": currSign +" ") + str.join('.');
}

alert(commafy(123545.3434));
动听の歌 2024-12-02 10:39:46

阅读您的评论后,您将进行编辑。

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, "$1,");    // 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, "$1 ");    // add spaces
      }
   }

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

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, "$1,");    // 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, "$1 ");    // add spaces
      }
   }

   return (typeof num[0] !== 'undefined'?int:'') 
        + (typeof num[1] !== 'undefined'?'.'+dec:'');
}
壹場煙雨 2024-12-02 10:39:46

这对我有用:

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

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;
}
╄→承喏 2024-12-02 10:39:46

当我搜索“向数字添加逗号”时,我发现这个小功能随处可见,并且它在大多数情况下都非常有效。它对我不起作用,因为我在表单中添加逗号以表示美元金额,并且希望在每次击键后都这样做。在我的例子中,它最多可以达到 9999,但是一旦达到五位数,就会得到这样的结果 - 1,4,0​​00。通过添加一行代码,我可以在每次击键后删除函数调用之前的所有逗号,如下所示:

    function addSomeCommas(number) {
      var parts = number.toString().split(".");
      parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
      return parts.join(".");
    }

    $("#dollarAmount").on("keyup change",function() {
      var num = $this).val();
      num = num.replaceAll(',', '');
      var commaNum = addSomeCommas(num);
      $(this).val(commaNum);
    });

I found this little function everywhere when searching for "adding commas to a number", and it works great for most cases. It didn't work for me because I was adding commas a dollar amount in a form, and wanted to do so after every keystroke. In my case it worked up to 9999, but once you get to five digits it would result in something like this - 1,4,000. By adding one line of code I was able to strip all commas prior to the function call after each keystroke like so:

    function addSomeCommas(number) {
      var parts = number.toString().split(".");
      parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
      return parts.join(".");
    }

    $("#dollarAmount").on("keyup change",function() {
      var num = $this).val();
      num = num.replaceAll(',', '');
      var commaNum = addSomeCommas(num);
      $(this).val(commaNum);
    });
温折酒 2024-12-02 10:39:46

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

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

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

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.

执妄 2024-12-02 10:39:46

这与 Ghostoy 的解决方案基本相同,但它修复了数千个数字无法正确处理的问题。将“5”更改为“4”:

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

This is basically the same as the solution from Ghostoy, but it fixes an issue where numbers in the thousands are not handled properly. Changed '5' to '4':

export function commafy(num) {
    const str = num.toString().split('.');
    if (str[0].length >= 4) {
        str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
    }
    if (str[1] && str[1].length >= 4) {
        str[1] = str[1].replace(/(\d{3})/g, '$1 ');
    }
    return str.join('.');
}
烟花易冷人易散 2024-12-02 10:39:46
//Code in Java
private static String formatNumber(String myNum) {
    char[] str = myNum.toCharArray();
    int numCommas = str.length / 3;
    char[] formattedStr = new char[str.length + numCommas];

    for(int i = str.length - 1, j = formattedStr.length - 1, cnt = 0; i >= 0 && j >=0 ;) {
        if(cnt != 0 && cnt % 3 == 0 && j > 0) {
            formattedStr[j] = ',';
            j--;
        }

        formattedStr[j] = str[i];
        i--;
        j--;
        cnt++;
    }
    return String.valueOf(formattedStr);
}
//Code in Java
private static String formatNumber(String myNum) {
    char[] str = myNum.toCharArray();
    int numCommas = str.length / 3;
    char[] formattedStr = new char[str.length + numCommas];

    for(int i = str.length - 1, j = formattedStr.length - 1, cnt = 0; i >= 0 && j >=0 ;) {
        if(cnt != 0 && cnt % 3 == 0 && j > 0) {
            formattedStr[j] = ',';
            j--;
        }

        formattedStr[j] = str[i];
        i--;
        j--;
        cnt++;
    }
    return String.valueOf(formattedStr);
}
音盲 2024-12-02 10:39:46

你可以用数学方法来做,具体取决于你想要分隔多少位数字,你可以从一位数字开始,10到100为2,依此类推。

function splitDigits(num) {
    num=Math.ceil(num);
    let newNum = '';
    while (num > 1000){
      let remain = num % 1000;
      num = Math.floor(num / 1000);
      newNum = remain + ',' + newNum;
    }
    return num + ',' + newNum.slice(0,newNum.length-1);
  }

You can do it mathematically, depending on how many digits you want to separate, you can start from one digit with 10 to 100 for 2, and so on.

function splitDigits(num) {
    num=Math.ceil(num);
    let newNum = '';
    while (num > 1000){
      let remain = num % 1000;
      num = Math.floor(num / 1000);
      newNum = remain + ',' + newNum;
    }
    return num + ',' + newNum.slice(0,newNum.length-1);
  }
段念尘 2024-12-02 10:39:46

首先,您应该使用 querySelector 选择输入,例如

let field = document.querySelector("input");

        field.addEventListener("keyup", () => {
            for (let i = 1 ; i <= field.value.length; i++) {
                field.value = field.value.replace(",", "");
            }
            let counter=0;

            for (let i = 1 ; i <= field.value.length; i++) {
                if ( i  % ((3 * (counter+1) ) + counter) ===0){
                    let tempVal =field.value
                    field.value = addStr(tempVal,field.value.length - i,",")
                    counter++;
                    console.log(field.value);
                }
            }
            // field.value = parseInt(field.value.replace(/\D/g, ''), 10);
            // var n = parseInt(e.target.value.replace(/\D/g,''),10);
            // e.target.value = n.toLocaleString();
        });

At first you should select the input with querySelector like:

let field = document.querySelector("input");

and then

        field.addEventListener("keyup", () => {
            for (let i = 1 ; i <= field.value.length; i++) {
                field.value = field.value.replace(",", "");
            }
            let counter=0;

            for (let i = 1 ; i <= field.value.length; i++) {
                if ( i  % ((3 * (counter+1) ) + counter) ===0){
                    let tempVal =field.value
                    field.value = addStr(tempVal,field.value.length - i,",")
                    counter++;
                    console.log(field.value);
                }
            }
            // field.value = parseInt(field.value.replace(/\D/g, ''), 10);
            // var n = parseInt(e.target.value.replace(/\D/g,''),10);
            // e.target.value = n.toLocaleString();
        });
岁月蹉跎了容颜 2024-12-02 10:39:46

如果您希望始终使用 2 位数字,

则使用 ES2017 padEnd 和 ES2015 解构。

function formatAmount(num: number): string {
  const [int, fra] = num.toString().split('.');
  return Number(int).toLocaleString() + '.' + (fra ?? '').padEnd(2, '0');
}

它将根据您的浏览器语言在 . 之前添加空格或逗号,并在末尾添加 2 位数字。

If you want always 2 digits

With ES2017 padEnd and ES2015 destructering.

function formatAmount(num: number): string {
  const [int, fra] = num.toString().split('.');
  return Number(int).toLocaleString() + '.' + (fra ?? '').padEnd(2, '0');
}

it will add spaces or commas before . in dependence on your browser language and add 2 digits at the end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文