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

我是这样做的:

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

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


当前回答

您可以使用此过程格式化所需货币。

var nf = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});
nf.format(123456.789); // ‘$123,456.79’

有关详细信息,您可以访问此链接。

https://www.justinmccandless.com/post/formatting-currency-in-javascript/

其他回答

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

我已经调整了您的代码以在TextBox(输入类型=“text”)中工作,这样我们就可以在不丢失光标的情况下实时输入和删除数字。如果您在删除时选择范围,它也会起作用。您可以自由使用箭头和起始/结束按钮。谢谢你节省了我的时间!

//function controls number format as "1,532,162.3264321"
function numberWithCommas(x) {
    var e = e || window.event;
    if (e.keyCode >= '35' && e.keyCode <= '40') return; //skip arrow-keys
    var selStart = x.selectionStart, selEnd = x.selectionEnd; //save cursor positions
    var parts = x.value.toString().split(".");
    var part0len = parts[0].length; //old length to check if new ',' would be added. Need for correcting new cursor position (+1 to right).

    //if user deleted ',' - remove previous number instead (without selection)
    if (x.selectionLength == 0 && (e.keyCode == 8 || e.keyCode == 46)) {//if pressed 8-backspace or 46-delete button
        var delPos = parts[0].search(/\d{4}/);
        if (delPos != -1) {//if found 4 digits in a row (',' is deleted)
            if (e.keyCode == 8) {//if backspace flag
                parts[0] = parts[0].slice(0, selStart - 1) + parts[0].slice(selEnd, parts[0].length);
                selEnd--;
                if (selStart > selEnd) selStart = selEnd;
            } else {
                parts[0] = parts[0].slice(0, selStart) + parts[0].slice(selEnd + 1, parts[0].length);
                selStart++;
                if (selEnd < selStart) selEnd = selStart;
            }
        }
    }

   var hasMinus = parts[0][0] == '-';
   parts[0] = (hasMinus ? '-' : '') + parts[0].replace(/[^\d]*/g, ""); //I'd like to clear old ',' to avoid things like 1,2,3,5,634.443216
   parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); //sets ',' between each 3 digits
   if (part0len < parts[0].length) { //move cursor to right if added new ','
       selStart++;
       selEnd++;
   } else if (part0len > parts[0].length) { //..or if removed last one ','
       selStart--;
       selEnd--;
   }
   x.value = parts.join(".");
   x.setSelectionRange(selStart, selEnd); //restoring cursor position
}
function saveSelectionLength(x) {
    x.selectionLength = x.selectionEnd - x.selectionStart;
}

要使用它,只需添加两个事件-onKeyUp和onKeyDown

<asp:TextBox runat="server" ID="val" Width="180px" onKeyUp="numberWithCommas(this);" onKeyDown="saveSelectionLength(this);"/>

可以使用浏览器的Intl对象以国际友好的方式插入千位分隔符:

Intl.NumberFormat().format(1234);
// returns "1,234" if the user's locale is en_US, for example

有关详细信息,请参阅MDN关于NumberFormat的文章,您可以指定区域设置行为或用户的默认设置。这是一个更加简单的方法,因为它尊重当地的差异;许多国家使用句点分隔数字,而逗号表示小数。

Intl.NumberFormat尚未在所有浏览器中都可用,但它在最新的Chrome、Opera和IE中都可以使用。Firefox的下一版本应该支持它。Webkit似乎没有实现时间表。

通用、快速、准确、功能简单

使用RegEx(快速准确)支持数字(浮点数/整数)/字符串/字符串中的多个数字智能井(不分组小数-兼容不同类型的分组)支持所有浏览器,特别是“Safari”和“IE”以及许多旧浏览器[可选]尊重非英语(波斯语/阿拉伯语)数字(+前缀)

TL;DR-完整版本功能(缩小):

//num:Number/s(字符串/数字),//sep:千位分隔符(字符串)-默认值:','//dec:十进制分隔符(字符串)-默认值:“.”(只有一个字符)//u:对语言字符的通用支持(String-RegEx字符集/类)-示例:“[\\d\\u0660-\\u0669\\u06f0-\\u06f3]”(英语/波斯语/阿拉伯语),默认值:“\\d”(英语)函数格式Nums(num,sep,dec,u){sep=sep||',';u=u||'\\d';if(typeof num!=‘string'){num=string(num);if(dec&&dec!=‘.')num=num.replace(‘.',dec);}return num.replace'),函数(a){return a.length==1?a+sep:a})}text='00000000英语或波斯语/阿拉伯语۱1778; 1779; 1780; 1781; 1782; 1783; 1784; 1785;/٠1633; 1634; 1635; 1636; 1637;٦这是123123.123123加上这个-123123和这10 100 1000 123123/12123(2000000)33333 100.00或任何类似的50万千克';console.log(formatNums(10000000.0012));console.log(formatNums(10000000.0012,'.',','));//德国的console.log(formatNums(文本,',','.','[\\d\\u0660-\\u0669\\u06f0-\\u06f4]');//尊重波斯语/阿拉伯数字<input-oninput=“document.getElementById('result').textContent=formatNums(this.value)”placeholder=“在此处键入数字”><div id=“result”></div>

为什么不满意其他答案?

Number.pr原型.toLocaleString()/Intl.NumberFormat(正确答案)若并没有好的论点,我们就不能期待同样的结果。此外,对于参数选项,我们仍然无法确定结果,因为它将使用本地设置和可能的客户端修改效果,或者浏览器/设备不支持它。>~ 2016年的浏览器支持,但到2021,仍有一些报告称,在某些情况下,如Safari或IE/Edge,不会按预期返回。toLocaleString()使用数字,Intl.NumberFormat使用字符串/数字;如果需要,字符串将被解析并舍入,因此:如果我们已经有一个非英文数字的本地化字符串,我们必须用英文数字替换数字,然后解析它,然后使用本地选项再次使用它。(如果它返回我们期望的结果)通常,在解析时,我们不能期望不丢失十进制零或大数字中的细节,也不能期望不尊重其他语言数字字符小数/千位分隔符的自定义不能超过语言选项,除非再次使用replace()+RegEx进行后置固定。(例如,在波斯语中,我们通常不使用建议的阿拉伯逗号,有时我们使用∕分数/除法斜线作为小数分隔符)环路中的性能低下不太好的RegEx方式(最快和一行方式)/\B(?=(\d{3})+\B)/它也会对小数进行分组。//123,123.123,123 !!!/(?<!\.\d+)\B(?=(\d{3})+\B)/使用了尚未很好支持的查找。请检查:https://caniuse.com/js-regexp-lookbehindhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#browser_compatibility注意:一般情况下,lookbacking可能会与原始RegEx结构相违背(因为分析器的工作方式应该像不缓冲原始数据一样),实际上它会使性能严重降低(在本例中约为30%)。我认为这是一段时间以来的要求。/\B(?=(?=\d*\.)(\d{3})+(?!\d))/只处理浮点数,忽略整数。.replace(/(?:[^.\d]|^)\d+/g,函数(a){return a.replace(/\B(?=(?:\d{3})+\B)/g,',');})(我的旧想法)使用2 RegEx。第一个查找整数部分,第二个放置分隔符。为什么可以混合使用两种功能?/(\..*)$|(\d)(?=(\d{3})+(?!\d))/g(@djulien的好主意-我投了赞成票)但当RegEx是全局的时,(\..*$即使最后有空格也可能出错。使用捕获组(例如:(\d))也会降低性能,因此如果可能,请使用非捕获组(示例:(?:\d)或如果函数中已经存在语句,让我们混合使用。在这种情况下,不使用捕获组可以提高约20%的性能,在/\B(?=(\d{3})+\B)/g与/\B?=(?:\d})+/B)/g的情况下,第二个捕获组的速度快约8%。关于正则表达式性能:注意:不同的方法、浏览器、硬件、系统状态、案例甚至ECMAScript上的更改都会影响性能检查结果。但一些逻辑上的改变应该会影响结果,我用这个例子作为视觉示例。使用像Numeral.js这样的库并不是简单任务所必需的函数。重代码/使用.split('.')或.toFixed()或Math.floor()的函数不准确。。。


最终结果:

没有最好的,应该根据需要来选择。我的排序优先级;

兼容性能力普遍性易于使用表演

toLocaleString()(兼容性-通用性)[本机函数]

如果您必须将数字和分组从英语更改为另一种语言如果你不确定你的客户语言如果你不需要确切的预期结果如果你不在乎Safari的旧版本

// 1000000.2301
parseFloat(num) // (Pre-fix) If the input is string
    .toLocaleString('en-US', {
        useGrouping: true // (Default is true, here is just for show)
    });
// 1,000,000.23

阅读更多信息:https://www.w3schools.com/jsref/jsref_tolocalestring_number.asp

Intl.NumberFormat()(功能-通用性-兼容性)[本机函数]

与toLocaleString()几乎相同+

支持货币、单位等任何语言的强大功能(现代浏览器)

// 1000000.2301
new Intl.NumberFormat('en-US', { // It can be 'fa-IR' : Farsi - Iran
    numberingSystem: 'arab'
}).format(num)
// ١٬٠٠٠٬٠٠٠٫٢٣

阅读更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat

有了这些本机函数选项,我们仍然无法期待:

精确结果(+不解析输入/不舍入/不转换大数字)接受其他语言数字作为输入自定义分隔符信任浏览器支持表演

所以你可能需要一个这样的函数:

formatNums()(兼容性-易于使用)

完整版本(功能)(不快于toLocaleString)-解释:

function formatNums(num, sep, dec, u) {
    // Setting defaults
    sep = sep || ','; // Seperator
    u = u || '\\d'; // Universal character set \d: 0-9 (English)
    // Mixing of Handeling numbers when the decimal character should be changed + Being sure the input is string
    if (typeof num != 'string') {
        num = String(num);
        if (dec && dec != '.') num = num.replace('.', dec); // Replacing sure decimal character with the custom
    }
    //
    return num.replace(RegExp('\\' + (dec || '.') + u + '+|' + u + '(?=(?:' + u + '{3})+(?!' + u + '))', 'g'),
        // The RegEx will be like /\.\d+|\d(?=(?:\d{3})+(?!\d))/g if not be customized 
        // RegEx explain:
        // 1) \.\d+  :  First try to get any part that started with a dot and followed by any much of English digits, one or more (For ignoring it later)
        // 2) |  :  Or
        // 3) \d  :  Get any 1 char digit
        // 3.1) (?=...)  :  That the next of that should be
        // 3.2) (?:\d{3})  :  3 length digits
        // 3.2.1) +  :  One or more of the group
        // 3.3) (?!\d)  :  ...till any place that there is no digits
        function(a) { // Any match can be the decimal part or the integer part so lets check it
            return a.length == 1 ? a + sep : a // If the match is one character, it is from the grouping part as item (3) in Regex explain so add the seperator next of it, if not, ignore it and return it back.
        })
}

函数格式Nums(num,sep,dec,u){sep=sep||',';u=u||'\\d';if(typeof num!=“字符串”){num=字符串(num);如果(dec&&dec!='.')num=num.replace('.',dec);}return num.replace(RegExp('\\'+(dec||'.')+u+'+|'+u+'(?=(?:'+u+‘{3})+(?!'+u'))','g'),函数(a){return a.length==1?a+sep:a})}console.log(formatNums(100000.2301));console.log(formatNums(100.2301));console.log(formatNums(-2000.2301));console.log(formatNums(123123123,','));console.log(formatNums('0000.000'));console.log(formatNums('50000000.00'));console.log(formatNums('5000000,00','',''));console.log(formatNums(5000000.1234,'',''));console.log(formatNums('۱۲۩۴گܞۏՀۛ/۹ۈ܄\ 1776; \1776;;',','、'、'/'、'[\d\\u0660-\\u0669\\u06f0-\\u069]'));

在这里播放示例:https://jsfiddle.net/PAPIONbit/198xL3te/

轻版本(性能)(比toLocaleString快约30%)

函数格式Nums(num,sep){sep=sep||',';return字符串(num).replace(/\.\d+|\d(?=(?:\d{3})+(?!\d))/g,函数(a){返回a.length==1?a+sep:a});}console.log(formatNums(100000.2301));console.log(formatNums(100.2301));console.log(formatNums(-2000.2301));console.log(formatNums(123123123,''));

检查RegEx(没有必要的功能):https://regexr.com/66ott

(num+'').replace(/\B(?=(?:\d{3})+\B)/g,',');(性能-兼容性)

如果输入为“指定/预定义”,则最佳选择。(和通常的价格一样,肯定不会超过3位小数)(比toLocaleString快约65%)

num=1000000;str='123123.100';console.log((num+'').replace(/\B(?=(?:\d{3})+\B)/g,','));console.log(str.replace(/\B(?=(?:\d{3})+\B)/g,','));

+

对于波斯语/阿拉伯语本地客户:

如果你的客户像在伊朗一样使用波斯语/阿拉伯数字进行输入,我认为最好的方法是不保留原始字符,而是在处理之前将其转换为英语,这样你就可以计算出来。

// ۱۲۳۴۵۶۷۸۹۰
function toEnNum(n) { // Replacing Persian/Arabic numbers character with English
    n.replace(/[\u0660-\u0669\u06f0-\u06f9]/g, // RegEx unicode range Persian/Arabic numbers char
        function(c) {
            return c.charCodeAt(0) & 0xf; // Replace the char with real number by getting the binary index and breaking to lowest using 15
        }
    );
}
// 1234567890

为了让它们看起来仍然是原始的,有两种方法:

CSS使用带有本地数字的波斯语/阿拉伯语字体(我选择)使用Intl.NumberFormat或以下函数将结果转换回:https://stackoverflow.com/a/13787021/7514010


我在这篇文章中的老学校函数:(比toLocalString快15%)

// 10000000.0012
function formatNums(n, s) {
    return s = s || ",", String(n).
    replace(/(?:^|[^.\d])\d+/g, // First this RegEx take just integer parts
        function(n) {
            return n.replace(/\B(?=(?:\d{3})+\b)/g, s);
        })
}
// 10,000,000.0012

我认为你的解决方案是我见过的最短的解决方案之一。我认为没有任何标准的JavaScript函数可以完成这类工作,所以您可能需要自己完成。

我检查了CSS3规范,看看是否可以在CSS中实现这一点,但除非您希望每个数字都有自己的<span>,否则我认为这是不可能的。

我确实在GoogleCode上发现了一个看起来很有前途的项目:灵活的js格式。我没有使用过它,但它看起来非常灵活,并且使用JsUnit进行了单元测试。开发人员也有很多关于这个主题的帖子(尽管很旧)。

请务必考虑国际用户:许多国家使用空格作为分隔符,并使用逗号将小数与数字的整数部分分开。