资讯专栏INFORMATION COLUMN

千分位分隔数字并自定义保留小数位数

caoym / 2791人阅读

摘要:实现思路使用正则,用数字中的小数点做匹配尾部参考,来匹配某个数字后面的一个或多个连续位数字,如果匹配到把该数字替换成自身加分隔符,如下示例分隔数字解释和之间有一个连续位数字,那么给后面添加一个分隔符得到结果。

功能:可实现不同符号分隔数字,可自定义分隔后数字保留的小数位数。
实现思路

    使用正则,用数字中的小数点做匹配尾部参考,来匹配某个数字后面的一个或多个连续3位数字,如果匹配到把该数字替换成自身加分隔符,如下:

示例

1、 分隔数字:123456.1

解释:3和.之间有一个连续3位数字(456),那么给3后面添加一个分隔符得到结果:123,456.1。

2、分隔数字:1234567.1

解释:1和.之间有两个连续3位数字(234和567),那么给1后面添加一个分隔符,然后数字4后面也存在一个连续三位数字(567),那么也给4后面添加一个分隔符,最终得到结果1,234,567.1

匹配的正则表达式
/(d)(?=(d{3})+.)/g;

这里最难理解的就是(?=(d{3})+.),且看语法:
x(?=y):正向肯定查找,匹配后面带有y的x项目

那么在这里意思是:查找一个和“.”之间带有一个或多个连续3位数字的数字(x)
最终实现
/**
 *num 要分隔的数字(必填)
 *n 保留的小数位数(可选)
 *symbol 分隔数字使用的符号(可选,默认为",")
 */ 
function splitNum(num,n,symbol) {
    if(!num)throw new Error("splitNum需要传入一个待转换的数据");
    if(typeof num!=="number")throw new TypeError("num参数应该是一个number类型");
    if(n<0)throw new Error("参数n不应该小于0");
    var hasDot=parseInt(num)!=num;//这里检测num是否为小数,true表示小数
    var m=(n!=undefined&&n!=null)?n:1;
    num=m==0?num.toFixed(m)+".":hasDot?(n?num.toFixed(n):num):num.toFixed(m);
    symbol=symbol||",";
    num=num.toString().replace(/(d)(?=(d{3})+.)/g,function(match, p1,p2) {
        return p1 + symbol;
    });
    if(n==0||(!hasDot&&!n)){//如果n为0或者传入的num是整数并且没有指定整数的保留位数,则去掉前面操作中的小数位
        num=num.substring(0,num.indexOf("."));
    }
    return num;
}
难点解惑

1、也许有人会问,这里是用“.”号做参考进行匹配的,如果传进来的数字是一个整数呢,不就没“.”号了吗,所以在方法内部定义了m变量使其在操作过程中总能有个“.”号。

2、num=m==0?num.toFixed(m)+".":hasDot?(n?num.toFixed(n):num):num.toFixed(m);

num=m==0?num.toFixed(m)+".":hasDot?(n?num.toFixed(n):num):num.toFixed(m);

作用:这里的操作保证的是小数传n、小数不传n、整数传n、整数不传n四种情况都能正确返回小数位数
详解:
1、如果m为零(传入n=0)则直接经toFixed操作后再后面补“.”
2、如果m不为0,
    a、如果传入数为小数
        a"、如果传了n表示要保留小数,那么需要num.toFixed(n)
        b"、如果没传n表示不需要对小数进行操作,直接返回原num
    b、如果传入数为整数
        a"、直接对num进行toFixed(m)操作

说明:该方法只适用于常用数字的操作,当数字超过一定位数时产生的精度问题这里暂不做处理

自己写的方法,如果有什么不足之处欢迎指出交流,这里的replace方法可参考我的另一篇文章
补充:更简单的原生方法

number类型可调用toLocalString()方法把他转成本地语言环境格式显示,经测试是可行的,但不需要携带参数,因为这些参数还是具有一定兼容性问题的,直接可以像下面使用,具体参见MDN:

var number=1234567891.23;
console.log(number.toLocaleString());//1,234,567,891.23

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107264.html

相关文章

  • ES6学习 第六章 数值的扩展

    摘要:前言本章介绍数值的扩展。本章原文链接数值的扩展进制表示法提供了二进制和八进制数值的新的写法,分别用前缀或和或表示。科学计数法里面,表示指数的或前后不能有分隔符。函数返回数值的双曲余弦函数可用表示。与数值的类型不同。 前言本章介绍数值的扩展。新增了很多方法,有些不常用的方法了解即可。本章原文链接:数值的扩展进制表...

    番茄西红柿 评论0 收藏2637
  • [PHP源码阅读]number_format函数

    摘要:上次讲到是如何解析大整数的,一笔带过了的处理,再详细阅读该函数的源码,以下是小分析。总结阅读完这个函数的源码,学习到的是浮动数与字符串的互相转换的实现细节,字符串与浮点数之间的关系较复杂,之后还要继续学习。 上次讲到PHP是如何解析大整数的,一笔带过了number_format的处理,再详细阅读该函数的源码,以下是小分析。 函数原型 string number_format ( flo...

    itvincent 评论0 收藏0
  • 简单学习 JavaScript 正则表达式

    摘要:对于对象,方法返回一个该正则表达式的字面量。显示显示正则表达式在的应用一个在字符串中执行查找匹配的方法,它返回一个数组或者在未匹配到时返回。 为什么要用正则表达式 简单的说:我们与字符串接触的频率非常之高,正则表达式可以极大的提高复杂文本分析的效率,快速匹配出复杂的字符串。 创建一个正则表达式 直接量语法(字面量) var expression = /pattern/flags ;...

    nevermind 评论0 收藏0
  • JS核心知识点梳理——正则篇(下)

    摘要:正则引言正则是一个前端必须掌握的知识。但是由于用的少,忘了记,记了忘,导致面试经常坐蜡。这里上篇先介绍正则的规则,下篇结合一些具体题目,带大家重新学习巩固一下正则,争取面试给自己加分。 正则 showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 引言 正则是一个前端必须掌握的知识。但是由于用的少,忘了记,记了忘,导致面...

    jemygraw 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<