1、用正则实现
// 千分位
function toThousands(n) {
const num = Number(n)
const re = /\d{1,3}(?=(\d{3})+$)/g
const n1 = num.toFixed(2).replace(/^(\d+)((\.\d+)?)$/, function(s, s1, s2) {
return s1.replace(re, '$&,') + s2
})
return n1
}
console.log(toThousands(1000000)) // 1,000,000.00
正则含义
1)/\d{1,3}(?=(\d{3})+$)/g
用于在数字串中查找并匹配最多三个数字的片段,同时它预示着后续的数字将以每三个一组的形式出现直至字符串的结尾。
正则表达式逐个分析:
- \d{1,3}:这部分匹配一到三个数字。\d 是一个字符类,代表任何一个数字(0-9),{1,3} 则指定这个字符类可以重复1到3次。
- (?=(\d{3})+$):这是一个正向前瞻断言(positive lookahead assertion)。它检查当前位置之后的字符串是否符合括号内的模式,但自身并不消耗任何字符。括号内的模式 (\d{3})+ 匹配三个数字的组合,并且至少出现一次。$ 表示字符串的结尾,所以这个正向前瞻断言确保了从当前位置开始直到字符串的末尾,剩下的部分必须是三个数字的组合重复出现。
- /g:全局匹配标志,表示在整个目标字符串中查找所有匹配项,而不仅仅停止在第一个匹配上。
则这个正则表达式的含义是:
这个正则表达式主要用于处理长数字串,比如货币或电话号码,其中数字需要按照每三个一组进行分组或分隔。例如,在处理一个大的数字如 1234567890 时,你可能希望它显示为 123,456,789,0。
这个正则表达式会找到第一个一到三个数字的组合,只要这个组合后面跟着的都是三个数字的组合直到字符串结束。例如,在 1234567890 中,123 是第一个匹配项,因为它后面是 4567890,这满足了每三个数字一组的条件。
2)/^(\d+)((\.\d+)?)$/
用于匹配整数或浮点数,但不包括科学记数法表示的数字。
正则表达式逐个分析:
- ^:表示匹配字符串的开始位置,确保整个字符串从这里开始符合模式。
- (\d+):这部分捕获一个或多个数字字符(\d 相当于 [0-9])。+ 表示前面的元素(在这里是 \d)至少出现一次。括号 () 用于创建一个捕获组,这意味着这部分匹配的文本可以被单独引用。
- ((\.\d+)?):这部分用于匹配一个可选的小数点后跟一个或多个数字。这里的结构稍微复杂一点:
- (?:...):非捕获组,意味着这部分不会被捕获为一个可以引用的组,仅用于分组。
- (\.\d+):匹配一个字面点号 . 后跟一个或多个数字,这部分是捕获组。
- ?:使得整个非捕获组 (?:\.\d+) 成为可选的,也就是说,这个小数点及后面的数字可以不存在。
- $:表示匹配字符串的结束位置,确保整个字符串在这里结束符合模式。
则这个正则表达式的含义是:
- 至少一个数字开头;
- 接着是零个或一个由小数点和至少一个数字组成的浮点数部分;
- 并且整个字符串只能包含这一个数字序列和可选的浮点数部分,不能有其他字符。
2、使用Intl.NumberFormat实现
Intl.NumberFormat对象是一个国际化的数字格式化API,它可以很方便地处理货币格式化。
function formatCurrency(num) {
return new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
}).format(num);
}
// 使用示例
console.log(formatCurrency(123456.789)); // 输出类似于 "123,456.79元"
此例子中:
- 'zh-CN' 是语言标签,用于指定中文(中国)的格式。
- style: 'currency' 指定输出样式为货币。
- currency: 'CNY' 指定货币类型为人民币。
- 世界上部分币种:美元(USD),欧元(EUR),日元(JPY),英镑(GBP),人民币(CNY),澳元(AUD),瑞士法郎(CHF),加元(CAD),墨西哥比索(MXN),新西兰元(NZD),港币(HKD),新加坡元(SGD),瑞典克朗(SEK),挪威克朗(NOK),丹麦克朗(DKK)
这个函数可以处理各种数字,自动添加千位分隔符和货币单位。你可以根据需要修改语言和货币设置。
如果你需要格式化其他货币,只需更改currency属性即可。例如,要格式化美元,可以将currency: 'CNY'更改为currency: 'USD'。
3、关于Intl的拓展
1)Intl是什么?
Intl 是 JavaScript 的一个内置命名空间,它提供了一系列的构造函数和辅助函数,用于处理与国际化(Internationalization,简称 i18n)相关的任务。Intl 对象及其相关 API 的设计目的是为了支持多种语言和地区的日期、时间、数字、货币、度量单位等的格式化和解析,使得 Web 应用程序能够以用户所在地区的本地化格式显示数据。
Intl 提供了以下几个主要的子类:
- Intl.DateTimeFormat:用于日期和时间的格式化和解析。它可以根据用户的语言和地区偏好,将日期和时间转换为相应的本地化格式。
- Intl.NumberFormat:用于数字和货币的格式化和解析。它可以将数字转换为带有适当千位分隔符、小数点和货币符号的本地化格式。
- Intl.Collator:用于文本排序。它可以根据用户所在地区的排序规则对文本进行比较和排序。
- Intl.PluralRules:用于处理复数形式。它可以根据数字的值返回正确的复数形式,这对于需要根据不同数量使用不同词汇的语言特别有用。
- Intl.RelativeTimeFormat:用于格式化相对时间,如“10分钟前”或“两天后”。
- Intl.ListFormat:用于格式化列表,如项目列表或选择列表,可以控制列表的格式(如并列、最后或单一项目)。
- Intl.DisplayNames:用于获取语言、地区、脚本和货币的可读名称。
这些 API 使得开发者无需了解各种语言和地区的具体格式细节,就能创建具有全球适用性的应用程序。例如,使用 Intl.NumberFormat 可以轻松地将数字格式化为不同的货币或数字格式,而 Intl.DateTimeFormat 可以处理日期和时间的本地化显示。
Intl API 的设计遵循了 ECMAScript 国际化 API 规范,它在现代浏览器中得到了广泛的支持,但在一些旧的浏览器中可能需要 polyfills(补丁库)来保证兼容性。
2)Intl的浏览器兼容性
- Chrome: 从版本 24 开始支持。
- Firefox: 从版本 27 开始支持。
- Safari: 从版本 7 开始支持,但在 Safari 10 之前不支持 compactDisplay 和 signDisplay 选项。
- Edge: 从版本 12 开始支持。
- Internet Explorer: 不支持。
- 移动浏览器: 大部分现代移动浏览器也支持,但IE Mobile不支持。
- Node.js: 从版本 0.12 开始支持。
注意:
- 特性支持: 虽然基本的 Intl.NumberFormat 支持广泛,但一些较新的选项(如 compactDisplay, notation, signDisplay 等)在某些旧版本的浏览器中可能不受支持。
- polyfill: 如果你的项目需要支持不兼容此API的浏览器(如 IE),你可以使用 polyfill,如 Intl.js 或 core-js,以实现跨浏览器兼容性。
- 默认地区与语言: 如果用户浏览器没有设置任何首选语言或地区,Intl.NumberFormat 将使用英语(en-US)作为默认值。