每三个数字加逗号或空格分组

Add commas or spaces to group every three digits

本文关键字:空格 数字 三个      更新时间:2023-09-26

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

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"

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

用'分隔成两部分。,并分别格式化。

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('.');
}

就这么简单:

var theNumber = 3500;
theNumber.toLocaleString();

这里有两个我认为可能有用的简洁方法:

  1. Number.prototype.toLocaleString

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

总之,你可以像下面这样简单地使用is:

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

如果你和我看到的不一样,因为我们忽略了两个参数,它将返回一个基于你的操作系统的字符串

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

    我们为什么要考虑这个?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
    

    最简单的方法:

    <标题> 1
    var num = 1234567890,
    result = num.toLocaleString() ;// result will equal to "1 234 567 890"
    
    <标题> 2 h1> 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教程/书籍

    中找到它们。

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

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

    当然,你可能想先对n做一些测试,以确保它是正确的,但这就是它的逻辑。

    编辑

    糟糕!错过了空格的部分!您可以使用与逗号相同的正则表达式,但使用空格代替逗号,然后反转结果。

    下面是一个基于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 : '');
    }
    

    我已经扩展了#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));
    

    看完你的评论,编辑完毕。

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

    这对我有用:

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

    假设您的使用示例不代表已经工作的代码,而是期望的行为,并且您正在寻找算法的帮助,我认为您已经在正确的轨道上使用任何小数分割。

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

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

    这与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('.');
    }
    
    //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);
    }
    

    你可以用数学方法来做,这取决于你想要分离多少个数字,你可以从一个数字开始,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);
      }
    

    首先,您应该选择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();
            });
    

    我在搜索"在数字中添加逗号"时到处都发现了这个小函数,它在大多数情况下都很有效。它不适合我,因为我在表单中为美元金额添加逗号,并且希望在每次击键后都这样做。在我的例子中,它工作到9999,但是一旦你得到五位数,它就会得到这样的结果- 14000。通过添加一行代码,我能够在每次击键之后删除函数调用之前的所有逗号,如下所示:

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