通用、快速、准确、功能简单
使用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