问题描述
今天在处理一个数字的格式显示问题时, 遇到下面的一些需求:
可以显示千分符
可以显示百分比
可以显示小数位数
如下图, 如果勾选的话就使能该项设置.
百分比和小数位数比较好解决, 百分比只需要在源数字后面加两个零再加上百分号; 小数只需要在小数点后面加零即可. 最主要的是千分符的处理, 好, 就来说千分符.
千分符问题
数字千分符的处理有很多处理方案, 最主要的有下面几种.
方法一: 循环遍历
思路:
将数字转换成字符串, 然后倒序遍历取值, 每取 3 个字符插入一个, 逗号, 直到遍历到第一个字符.
代码很简单, 如下:
- function numberFormat(num) {
- let result = '';
- let count = 1;
- let nums = num.toString();
- for (let i = nums.length - 1; i>= 0; i--) {
- result = nums.charAt(i) + result;
- if (!(count % 3) && i != 0) {
- result = ',' + result;
- }
- count++;
- }
- return result;
- }
- numberFormat(12345678); // 12,345,678
方法二: 正则
思路:
该正则的思路就是从数字的第一个字符开始找, 找到满足该数字后面的数字个数为 3 的倍数的这个数字, 然后在该数字替换成数字, 的形式, 然后继续往下找......
语法如下:
let regExp = /(\d)(?=(\d{3})+$)/g;
示例:
String(12345678).replace(/(\d)(?=(\d{3})+$)/g, "$1,");
解释:
首先 \ d 表示数字, 然后以?=(\d{3})+ 结尾的即满足条件. 所以最主要是这个 ?=(\d{3})+ 表达式.
正向预测 ?=n, 表示匹配任何其后紧接指定字符串 n 的字符串. 再结合 \ d 表示, 如果一个数字后面满足字符串 n 这个规则, 那么就将匹配到的这个数字 (假如是 1) 替换成 1,.
所以现在的问题是字符串 n 这个规则是什么, 是(\d{3})+ 这个东西, 这个表示数字的个数为 3 的倍数(倍数为 1~n 之间).
所以整个表达式的意思就是: 从第一个数字开始看起, 看这个数字后面的数字个数是不是 3 的倍数, 是的话将这个数字 (假如是 1) 替换成 1, 的形式, 然后继续下一个数字直到结尾.
说明:
g 是表示全局匹配的修饰符, 全局匹配指查找所有匹配而非在找到第一个匹配后停止.
$ 是表示结尾的量词, 如 n$, 匹配的是任何以 n 为结尾的字符串.
\d 是查找数字的元字符.
n{X}是匹配包含 X 个 n 的序列的字符串的量词.
+ 匹配前面的子表达式一次或多次;* 匹配前面的子表达式 0 次或多次.? 匹配前面的子表达式 0 次或 1 次, 或指明一个非贪婪限定符.
?=n 正向预查, 用于匹配任何其后紧接指定字符串 n 的字符串.
match() String 对象的方法, 作用是找到一个或多个正则表达式的匹配.
replace() String 对象的方法, 作用是替换与正则表达式匹配的子串.
\B 是表示匹配非单词边界的元字符, 与其互为补集的元字符是 \ b, 表示匹配单词边界.
方法三(推荐):toLocaleString
根据 MDN 解释, number.toLocaleString() 方法返回这个数字 number 在特定语言环境下的表示字符串.
简单的使用:
- var number = 3500;
- console.log(number.toLocaleString()); // 3,500
我们直接调用该函数就可以得到问题的结果. 但其实, 该函数的功能不止于此, 这就需要分析它的参数了.
语法:
numObj.toLocaleString([locales [, options]])
locales: (可选)表示以哪国的数字表示形式.
options: (可选)表示数字的显示样式(比如要不要显示小数位数, 显示几位? 要不要显示百分比? 等等)
locales
一般可以填下面几个数值:
en-US : 美国( 中文场景下默认值)
zh-CN : 中国
en-GB : 英国
ko-KR : 韩国
ar-EG : 阿拉伯
de-DE : 德国
en-IN : 印度
ja-JP : 日本
- ...
- (更多的国家参考链接: ISO Language Code Table http://www.lingoes.net/en/translator/langcode.htm )
- options
options 对象的属性就有很多了, 下面列举一个常用的属性.
style : 默认为 decimal , 表示十进制格式, currency 表示货币格式, percent 表示百分比格式.
currency : 如果 style 设置为 currency, 则该属性设置货币符号(USD 表示美元, EUR 表示欧元, or CNY 是人民币等等, 更多符号参考链接: )
useGrouping : 是否使用千分符, 默认为 true
minimumIntegerDigits
: 设置整数最小位数(当整数位数不足时, 在前面加 0)
minimumFractionDigits
: 设置小数数最小位数.
而这些属性不仅可以满足文章开头提出的问题, 也可以满足我们日常常用到的数字的格式表示. 那么我们就来康康怎么使用吧!
示例:
设置整数部分为 5 位, 小数部分为 2 位, 不使用千分符格式
- Number(123).toLocaleString('zh-CN', {
- style: 'decimal',
- useGrouping: false,
- minimumIntegerDigits : 5,
- minimumFractionDigits: 2
- }) // 00123.00
设置两位小数的百分比显示
- Number(123).toLocaleString('zh-CN', {
- style: 'percent',
- minimumFractionDigits: 2
- }) // 12,300.00%
设置欧元货币
- Number(123).toLocaleString('zh-CN', {
- style: 'currency',
- currency: 'EUR',
- minimumFractionDigits: 2
- }) // €123.00
toLocaleString 扩展
除了数字本地化格式之外, 还有日期, 数组, 对象等等一系列的本地化处理, 由于篇幅有限, 这里不再展开, 可以自行去 MDN 查找相关内容, 基本上用法都是类似的.
最后, 如果看完有收获, 就动动小手点个赞再走呗, 笔芯.
来源: https://www.cnblogs.com/lvonve/p/12067970.html