千分位分隔數字並自定義保留小數位數

功能:可實現不一樣符號分隔數字,可自定義分隔後數字保留的小數位數。
實現思路

    使用正則,用數字中的小數點作匹配尾部參考,來匹配某個數字後面的一個或多個連續3位數字,若是匹配到把該數字替換成自身加分隔符,以下:javascript

  • 示例

一、 分隔數字:123456.1java

解釋:3和.之間有一個連續3位數字(456),那麼給3後面添加一個分隔符獲得結果:123,456.1。正則表達式

二、分隔數字:1234567.1post

解釋: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;
}
難點解惑
  • 一、也許有人會問,這裏是用「.」號作參考進行匹配的,若是傳進來的數字是一個整數呢,不就沒「.」號了嗎,因此在方法內部定義了m變量使其在操做過程當中總能有個「.」號。
  • 二、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四種狀況都能正確返回小數位數
詳解:
一、若是m爲零(傳入n=0)則直接經toFixed操做後再後面補「.」
二、若是m不爲0,
    a、若是傳入數爲小數
        a'、若是傳了n表示要保留小數,那麼須要num.toFixed(n)
        b'、若是沒傳n表示不須要對小數進行操做,直接返回原num
    b、若是傳入數爲整數
        a'、直接對num進行toFixed(m)操做

說明:該方法只適用於經常使用數字的操做,當數字超過必定位數時產生的精度問題這裏暫不作處理code

本身寫的方法,若是有什麼不足之處歡迎指出交流,這裏的replace方法可參考個人 另外一篇文章

補充:更簡單的原生方法

number類型可調用toLocalString()方法把他轉成本地語言環境格式顯示,經測試是可行的,但不須要攜帶參數,由於這些參數仍是具備必定兼容性問題的,直接能夠像下面使用,具體參見MDNip

var number=1234567891.23;
console.log(number.toLocaleString());//1,234,567,891.23
相關文章
相關標籤/搜索