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

我是这样做的:

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

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


当前回答

使用正则表达式

function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(toCommas(123456789)); // 123,456,789

console.log(toCommas(1234567890)); // 1,234,567,890
console.log(toCommas(1234)); // 1,234

使用toLocaleString()

var number = 123456.789;

// request a currency format
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €

// the Japanese yen doesn't use a minor unit
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457

// limit to three significant digits
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000

ref MDN:Number.protype.toLocaleString()

使用国际号码格式()

var number = 123456.789;

console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"

// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"

// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));

// expected output: "1,23,000"

参考Intl.NumberFormat

在这里演示<script type=“text/javascript”>//使用正则表达式函数到逗号(值){return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g,“,”);}函数命令(){var num1=文档.myform.number1.value;//使用正则表达式document.getElementById('result1').value=toCommas(parseInt(num1));//使用toLocaleString()document.getElementById('result2').value=parseInt(num1).toLocaleString('ja-JP'{style:'货币',货币:'日元'});//使用国际号码格式()document.getElementById('result3').value=新Intl.NumberFormat('ja-JP'{style:'货币',货币:'日元'}).格式(num1);}</script><FORM NAME=“myform”><INPUT TYPE=“text”NAME=“number1”VALUE=“123456789”><br><INPUT TYPE=“button”NAME=“button“Value=”=>“onClick=”commas()“><br>使用正则表达式<br><INPUT TYPE=“text”ID=“result1”NAME=“result1”VALUE=“”><br>使用toLocaleString()<br><INPUT TYPE=“text”ID=“result2”NAME=“result2“VALUE=”“><br>使用国际号码格式()<br><INPUT TYPE=“text”ID=“result3”NAME=“result3“VALUE=”“></FORM>表演http://jsben.ch/sifRd

其他回答

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

使用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进行了单元测试。开发人员也有很多关于这个主题的帖子(尽管很旧)。

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

我找到了一种适用于所有情况的方法。CodeSandbox示例

function commas(n) {
  if (n < 1000) {
    return n + ''
  } else {
    // Convert to string.
    n += ''

    // Skip scientific notation.
    if (n.indexOf('e') !== -1) {
      return n
    }

    // Support fractions.
    let i = n.indexOf('.')
    let f = i == -1 ? '' : n.slice(i)
    if (f) n = n.slice(0, i)

    // Add commas.
    i = n.length
    n = n.split('')
    while (i > 3) n.splice((i -= 3), 0, ',')
    return n.join('') + f
  }
}

这就像诺亚·弗雷塔斯(Noah Freitas)的答案,但支持分数和科学记数法。

我认为如果性能不受关注,toLocaleString是最好的选择。

edit:这里有一个CodeSandbox,其中包含一些示例:https://codesandbox.io/s/zmvxjpj6x

使用正则表达式

function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(toCommas(123456789)); // 123,456,789

console.log(toCommas(1234567890)); // 1,234,567,890
console.log(toCommas(1234)); // 1,234

使用toLocaleString()

var number = 123456.789;

// request a currency format
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €

// the Japanese yen doesn't use a minor unit
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457

// limit to three significant digits
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000

ref MDN:Number.protype.toLocaleString()

使用国际号码格式()

var number = 123456.789;

console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"

// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"

// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));

// expected output: "1,23,000"

参考Intl.NumberFormat

在这里演示<script type=“text/javascript”>//使用正则表达式函数到逗号(值){return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g,“,”);}函数命令(){var num1=文档.myform.number1.value;//使用正则表达式document.getElementById('result1').value=toCommas(parseInt(num1));//使用toLocaleString()document.getElementById('result2').value=parseInt(num1).toLocaleString('ja-JP'{style:'货币',货币:'日元'});//使用国际号码格式()document.getElementById('result3').value=新Intl.NumberFormat('ja-JP'{style:'货币',货币:'日元'}).格式(num1);}</script><FORM NAME=“myform”><INPUT TYPE=“text”NAME=“number1”VALUE=“123456789”><br><INPUT TYPE=“button”NAME=“button“Value=”=>“onClick=”commas()“><br>使用正则表达式<br><INPUT TYPE=“text”ID=“result1”NAME=“result1”VALUE=“”><br>使用toLocaleString()<br><INPUT TYPE=“text”ID=“result2”NAME=“result2“VALUE=”“><br>使用国际号码格式()<br><INPUT TYPE=“text”ID=“result3”NAME=“result3“VALUE=”“></FORM>表演http://jsben.ch/sifRd

我很惊讶没有人提到Number.prototype.toLocaleString。它是在JavaScript 1.5中实现的(于1999年引入),因此基本上所有主要浏览器都支持它。

变量n=34523453.345;console.log(n.toLocaleString());//"34,523,453.345"

通过包含Intl,它也可以在Node.js中工作

如果你想要一些不同的东西,Numeral.js可能会很有趣。