JavaScript處理數字分位符號

2021-02-19 W3cplus

昨天做一個頁面有一個需求,需要把伺服器取過來的數字(也有可能是數字字符串),將小數點前的數字每隔三位添加一個逗號(前面數是一個四位數的值)。比如取到的值是123456,要將其轉換成123,456。搜索了一下,這叫數字分們符號。

為了方便閱讀小數點前後的數字可以被分組,由於國際上語言裡最常見的數字讀法是千位分位,寫法的分組也是在千位數上。 如果當地習俗是用句點作小數點,千位的分號一般是逗號或空格。如果習俗裡小數點是逗號,千位分號一般是句點或空格。由於可能產生歧義,國際標準建議、國際度量衡局更是要求用空格而不要用逗號或點。

不同國家有不同的標準要求,我們看看我國的標準:

為便於閱讀,四位以上的整數或小數,可採用以下兩種方式分節:

千分撇: 整數部分每三位一組,以,分節。小數部分不分節。四位以內的整數可以不分節。如:624,000、 92,300,000、19,351,235.235767,1256

千分空: 從小數點起,向左和向右每三位數字一組,組間空四分之一個漢字,即二分之一個阿拉伯數字的位置。四位以內的整數可以不加千分空。如:55 235、 367.346、 23 98 235、 358.238、 368

可見,中國正式場合的數字用法並非是以萬位數為一組來分節的。諸如123,4567.89的表示法是錯誤的。

JavaScript如何處理數字分位符

在這樣的一個實際需求當中,取到的值不外呼是兩種,其一它就是一個數字類型(整型123456或者浮點型12345.09),其二是一個數字字符串,比如"123456"。那回到主題上,現在需要將這樣的數字或字符串做處理。

需要創建一個函數,比如addCommas(),並且給這個函數傳遞一個參數val。需要注意的是,這個val值有可能是數字類型,也有可能是字符類型。

不管獲取的val是什麼類型,首先通過toString()方法,將其轉換成字符串

由於取到的val值有可能是一個浮點數,而我們是需要給小數點前面的整數部分添加分位符號,;在JavaScript中可以通過split(".")將這個val轉換成一個數組aIntNmu。如果val值是一個整數,那麼得到的數組只有一個值,如果val是一個浮點數,那麼將會以小數點為分隔點,數整會有兩個元素值。我們要處理的將是aIntNum[0]。

通過正則replace()主法給aIntNum[0]做替換,這裡需要一個正則規則,比如/(\d+)(\d{3})/。正則這部分,對於我這樣的菜鳥而言還是很吃力的,不過這有個在線工具,可以檢測並解釋其函數。

如果你想讓JavaScript處理數字千分位更符合國家的標準,那麼在做數據替換時,還需要做一個條件判斷。比如說,只有當aIntNum[0].length大於或等於5的時候才添加分位符。

返回處理的數字

上面方法是通過數組來處理的,其實還可以直接通過字符串處理來解決。比如通過indexOf(".")對數字分隔,再配合for循環、charAt()和substr()等方法給數字添加分位符。接下來,我們一起看看代碼具體如何寫。

數組方案

根據前面的介紹的,先用數組的方式來做:

function addCommas(val) {        var aIntNum = val.toString().split('.');        var iIntPart = aIntNum[0];        var iFlootPart = aIntNum.length > 1 ? '.' + aIntNum[1] : '';    var rgx = /(\d+)(\d{3})/;        if (iIntPart.length >= 5) {                while (rgx.test(iIntPart)) {            iIntPart = iIntPart.replace(rgx, '$1' + ',' + '$2');        }    }    return iIntPart + iFlootPart;}

上面的方法生不生效,難證一下就知道了:

addCommas(1234); addCommas(12345);addCommas(123456);addCommas(123456.4321);addCommas(123456.54321);addCommas(123456.654321);

上面的方法只能小數點前面的數做了處理,如果需要對小數點後面的也做相應的處理,就需要做一下處理:

function addCommas(val) {        var aIntNum = val.toString().split('.');        var iIntPart = aIntNum[0];        var iFlootPart = aIntNum.length > 1 ? '.' + aIntNum[1] : '';    var rgx = /(\d+)(\d{3})/;        if (iIntPart.length >= 5) {                while (rgx.test(iIntPart)) {            iIntPart = iIntPart.replace(rgx, '$1' + ',' + '$2');        }    }        if (iFlootPart && iFlootPart.length >= 5) {                while (rgx.test(iFlootPart)) {            iFlootPart = iFlootPart.replace(/(\d{3})/g, '$1 ');        }    }        return iIntPart + iFlootPart;}

調試器裡繼續跑一下測試代碼:

addCommas(1234);addCommas(12345);addCommas(123456);addCommas(123456.4321);addCommas(123456.54321);addCommas(123456.654321);

效果是有,但感覺怪怪的。

上面的代碼可以精簡一下,變成這樣:

function addCommas(val) {    var aIntNum = val.toString().split('.');    if (aIntNum[0].length >= 5) {        aIntNum[0] = aIntNum[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');    }    if (aIntNum[1] && aIntNum[1].length >= 5) {        aIntNum[1] = aIntNum[1].replace(/(\d{3})/g, '$1 ');    }    return aIntNum.join('.');}

最後得到的效果就是一樣。

將上面代碼中的正則條件換換,也一樣可以達到相同的效果:

function addCommas(val) {    var aIntNum = val.toString().split(".");    if (aIntNum[0].length >= 5) {        aIntNum[0] = aIntNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");    }    if (aIntNum[1] && aIntNum[1] >= 5) {        aIntNum[1] = aIntNum[1] ? aIntNum[1].replace(/\B(?=(\d{3})+(?!\d))/g, " ") : " ";    }    return aIntNum.join(".");}

字符串方案

前面也說了,除了將傳參轉換成數組去處理之外,還可以直接對傳參進行字符串的操作。下面收集了幾種方法,雖然達到需求,但還是略有不同之處。比如小數部分用的不是空格分開,而是使用逗號分開。另外一點,就是沒找到如何超過四位數才進行分隔處理。希望有高手能指點其中不足之處。

方法1

function addCommas(val) {    while (/(\d+)(\d{3})/.test(val.toString())) {        val = val.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');    }    return val;}

方法2

function addCommas(val) {    var sIntNum = val.toString(),        bIndex = sIntNum.indexOf('.');    return sIntNum.replace(/\d(?=(?:\d{3})+(?:\.|$))/g, function($0, i) {        return bIndex < 0 || i < bIndex ? ($0 + ',') : $0;    });}

方法3

function addCommas(val) {    return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");}

方法4

function addCommas(val) {    return (val + "").replace(/\b(\d+)((\.\d+)*)\b/g, function(a, b, c) {        return (b.charAt(0) > 0 && !(c || ".").lastIndexOf(".") ? b.replace(/(\d)(?=(\d{3})+$)/g, "$1,") : b) + c;    });}

總結

上面整理了使用數組或者直接操作字符串的幾種方法,將一個數字或數字字符串,按照千分位的方式給其添加對應的分隔符,比如,或空格。雖然達到了一定的需求,但感覺裡面的還存在一定的問題,只是沒有找到問題所在。希望大嬸們指點其中不對之處,如果您有更好的方案,歡迎在下面的評論中與我們一起分享。

擴展閱讀

文章涉及到圖片和代碼,如果展示不全給您帶來不好的閱讀體驗,歡迎點擊文章底部的 閱讀全文。如果您覺得小站的內容對您的工作或學習有所幫助,歡迎關注此公眾號。

W3cplus.com

————————————

記述前端那些事,引領web前沿

長按二維碼,關注W3cplus

相關焦點

  • Javascript去除字符串中的點或其他符號
    在前端上使用javascript進行操作的。測試了兩次沒有好用,程序直接把整個字符串都進行了替換,在考慮這個是為什麼呢?javascript(請忽略此配圖)示例var ip = data.field.ip.replace(/.
  • 探秘JavaScript中的六個字符
    -1370.html原文:http://jazcash.com/a-javascript-journey-with-only-six-characters/JavaScript 是一個奇怪而有趣的語言,我們可以寫一些瘋狂卻仍然有效的代碼。
  • JavaScript是什麼
    完成與後臺處理程序數據交互。【1.發請求{要} 2.處理數據】簡單的具體操作:1.直接向html文件中寫出標記和內容。2.對事件的反應3.改變 HTML 內容4.改變 HTML 圖像5.改變 HTML 樣式6.驗證輸入
  • 七天學會javascript第一天javascript介紹
    javascript介紹javascript數據類型javascript運算符javascript對象javascriptjavascript :客戶端編程。javascript是由客戶端去解釋運行的。怎麼引入javascript 呢?
  • 網頁技巧:妥善處理JavaScript中的錯誤
    'document.forms.0.firstName.value' is null or not an object 單個catch塊可以處理所有問題,但是多個catch語句可以被用來處理特定的錯誤。這個問題在下個部分會涉及到。用try/catch語句可以很容易地處理不可預見的錯誤。
  • Javascript每日一學-如何使用Javascript格式化數字,金額
    在前端開發中經常會遇到這樣一種需求,使用Javascript格式化數字進行輸出。最常見的是金額,比如人民幣最小表示單位為分,一般需要精確到小數點後兩位數字,而且整數位每隔三位數字需要用逗號隔開。今天我們就一起來看看如何使用原生Javascript和開源類庫來實現這樣一種功能吧。
  • 第五篇:JavaScript事件處理
    <head><title>JavaScript開發案例</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><script type="text/javascript
  • 8個簡單的JavaScript數字方法
    英文 | https://medium.com/front-end-weekly/8-javascript-number-methods-as-simple-as-possible-c1cd73fbff6f
  • JavaScript中的「黑話」
    字符串與數字相加時會將數值默認轉為字符串,因此有了一下將數字轉為字符串的快捷方法:'' + 1。& 與 &&如何你是從類C語言過來的話,請拋棄之前的刻板印象:&可以充當邏輯操作符號。在JavaScript中,&只能進行位運算。&,它表示按位與,此運算符需要兩個數字並返回一個數字。
  • 走近 (javascript, 函數式)
    在函數式編程裡,把要處理的數據看做一個在許多函數中流動的數據流。再將聲明的函數模塊組合出正確的函數組合,讓數據「流」過一串函數後達到想要的目的。javascript 對函數式編程的支持在 javascript 中,函數是一等的,也就是說,在 javascript 中,函數本身也是一個值。
  • JavaScript快速入門
    主要用於處理網頁中的前端驗證信息。所謂的前端驗證,就是檢查用戶的內容是否符合定義的規則。一個完整的JavaScript實現包含了三個部分:ECMScript、DOM和BOM,我們所要講解的也就是這三個部分。2.JavaScript語言的特點是一門解釋型語言。類似於C和java的語法結構。是一門動態語言。
  • Javascript 生成器
    在 javascript 中,如果想要使用生成器,則需要: 定義特殊的生成器函數 調用該函數創建一個生成器對象 在循環中使用該生成器對象,或直接調用其 方法 我們以下面這個簡單的程序做為起點,並執行以下每個步驟:
  • 前端設計-JavaScript簡單數字時鐘開發實例
    01所需素材本數字時鐘設計實現格式為00:00:00類型結構的數字時鐘,因此需要準備時鐘顯示相關數字及間隔符號的素材。ID標籤值對應數字8顯示效果在實際實現中由於8個DIV結構是固定的,包含了兩個分割符號,這部分可以直接設置為分割符號,如下所示:
  • 數字符號的變遷
    了解了古埃及和古巴比倫人的數字符號,再來看看古羅馬人的數字符號。羅馬數字的歷史可以追溯到公元前8世紀的古羅馬帝國時代。和其它所有的古老的數字符號一樣,羅馬數字也是源於自然界的象形符號。如下圖所示,羅馬數字符號源於人類的手指數量並配上一定大的手勢。
  • JavaScript 基礎語法
    需要用到script標籤,JS代碼書寫在script標籤之間;用type屬性來識別script標籤之間的內容,我們想在script標籤裡面書寫JS,需設置type屬性值為text/javascript。
  • 20個常用的JavaScript簡寫技巧
    箭頭函數 參考:JavaScript Arrow function https://jscurious.com/javascript-arrow-function/ 8. 模板字符串 我們一般使用 + 運算符來連接字符串變量。
  • C++、Java、JavaScript中的正則表達式
    我們從網易的郵箱註冊頁面可以看到126郵箱的用戶名需要符合以下的格式:6~18個字符,可使用字母、數字、下劃線,需以字母開頭。因為還有一個以非數字字母開頭的字符,所以^[a-zA-Z]w{5,17}表示:「6~18個字符,可使用字母、數字、下劃線,需以字母開頭」@126.com:表示符合以上規則的用戶名後跟上@126.com字符串,即組成一個郵箱地址。
  • 《出版物上數字用法》《標點符號用法》《中國人名
    ,《出版物上數字用法》《標點符號用法》《中國人名漢語拼音字母拼寫規則》三項國家標準於2011年發布,近期陸續實施。此三項標準廣泛應用於新聞出版、文化教育、信息處理等眾多領域,對社會語言文字應用的規範化標準化具有重要作用。  《出版物上數字用法的規定》《標點符號用法》是上世紀90年代中期由國家語委組織研製、國家質量技術監督局發布的國家標準。近二十年來,社會生活發生了巨大變化,需要根據實際使用狀況和社會需求對原標準進行修訂。
  • 數字符號體系
    這也同樣表明,在數字符號體系方面,西方國家和亞洲國家有很大的差別。
  • 記帳憑證數字的書寫要求
    填制記帳憑證時,數字的書寫必須符合下列要求:  (1)阿拉伯數字在書寫時,不得連筆寫,必須一個一個地寫。阿拉伯數字金額前必須書寫貨幣幣種符號或者貨幣名稱的簡寫和幣種符號(例如,¥、£、$)。幣種符號與阿拉伯數字之間不得留有空白(例如,人民幣18890元,應寫為:¥18890,不得寫為¥18890)。