最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 利用正则实现千分位分隔| 8月更文挑战

    正文概述 掘金(答案cp3)   2021-08-03   747

    前言

    在一些涉及到比较大的数字的场景中,比如人数,金额等,我们常常需要对这些数字进行千分位,然后逗号分隔,这样会比较好阅读。

    比如

    123456789
    

    如果是千分位分隔

    123,456,789
    

    对比这两种,我们肯定是选择第二种,方便阅读。

    实现

    那怎么实现呢?

    一般是利用正则表达式

    function formatNumber(num) {
      const reg = /(\d)(?=(\d{3})+$)/g
      return num.toString().replace(reg, '$1,')
    }
    formatNumber(12345678) // "12,345,678"
    formatNumber(8765432188) // "8,765,432,188"
    

    测试通过。

    但是这是基于数字是整数型的正则,如果你的数字是有小数点的,结果如下

    formatNumber(1234.5678) // "1234.5,678"
    

    期望是"1,234.5678",不需要对小数点部分做千分位分隔,只需要对整数部分做千分位分隔,

    实际是 "1234.5,678"

    所以需要对正则进行优化。

    function formatNumber(num) {
      const reg = /(\d)(?=(\d{3})+\.)/g
      return num.toString().replace(reg, '$1,')
    }
    formatNumber(1234.5678) // "1,234.5678"
    formatNumber(1234) // "1234"
    

    从上面例子可以看到,

    如果数字带有小数点,则是有效果的

    但是如果数字是没有小数点的,这个正则是不起作用的, 所以需要对两个正则整合起来,实现对整数和小数的支持

    function formatNumber(num) {
      num = num.toString()
      let reg = num.indexOf('.') > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(\d{3})+$)/g
      return num.replace(reg, '$1,')
    }
    formatNumber(1234.5678) // "1,234.5678"
    formatNumber(1234) // "1,234"
    

    下面对正则/(\d)(?=(\d{3})+$)/g/(\d)(?=(\d{3})+\.)/g进行分析:

    1. 这个正则主要是利用d{3}每3位数字匹配一次,匹配到就对前面的那个数字加上逗号,以此类推。
    2. 正则这里加了$.,是为了优先后面的凑成3位,开头如果不足3位就不处理。
    3. 这里还使用了正则一个表达式(?=pattern),术语叫零宽断言,或者也叫正向肯定预查

    实现千分位分隔,核心点就是这个,下面来讲讲这个正则表达式。

    零宽断言(正向肯定预查)

    (?=pattern), 是指配合正则表达式进行匹配,但是不获取该匹配。下次匹配还是从该位置开始。

    配合例子来讲会比较好理解:

    var regA = /答案(?=cp3)/
    console.log('答案cp3'.match(regA)) // ["答案"]
    
    var regB = /cp3(?=cp3)/g
    console.log('cp3cp3cp3cp3'.match(regB)) // ["cp3", "cp3", "cp3"]
    

    第一个例子可以看到匹配到了答案cp3,但是只获取到了答案cp3不获取

    第二个例子可以看到匹配到了cp3cp3,只获取到了cp3,下次匹配从第二个cp3开始,以此类推,最终输出三个cp3

    结合上面的千分位分隔例子,因为我们使用了零宽断言,因为它下次匹配还是从该位置开始,所以就导致每个数字都会被匹配到,直到结尾

    let reg = /(\d)(?=(\d{3})+)/g
    '1234567890'.replace(reg, (match,$1, $2, index, str) => {
     console.log(match,$1, $2, index, str)
     return $1 + ','
    })
    
    输出 1 1 890 0 1234567890
    输出 2 2 678 1 1234567890
    输出 3 3 789 2 1234567890
    输出 4 4 890 3 1234567890
    输出 5 5 678 4 1234567890
    输出 6 6 789 5 1234567890
    输出 7 7 890 6 1234567890
    返回 "1,2,3,4,5,6,7,890"
    

    所以我们在零宽断言里面加上$或者.去约束条件,限制优先匹配结尾,开头不足3位就不处理

    let reg = /(\d)(?=(\d{3})+$)/g
    '1234567890'.replace(reg, (match,$1, $2, index, str) => {
     console.log(match,$1, $2, index, str)
     return $1 + ','
    })
    输出 1 1 890 0 1234567890
    输出 4 4 890 3 1234567890
    输出 7 7 890 6 1234567890
    返回 "1,234,567,890"
    

    这样子就没有问题了。

    总结

    以上就是利用正则实现千分位分隔的总结

    完整代码:

    function formatNumber(num) {
      num = num.toString()
      let reg = num.indexOf('.') > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(\d{3})+$)/g
      return num.replace(reg, '$1,')
    }
    

    起源地下载网 » 利用正则实现千分位分隔| 8月更文挑战

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元