問題描述
今天在處理一個數字的格式顯示問題時,遇到下面的一些需求:
- 可以顯示千分符
- 可以顯示百分比
- 可以顯示小數位數
如下圖,如果勾選的話就使能該項設置。
百分比和小數位數比較好解決,百分比只需要在源數字后面加兩個零再加上百分號;小數只需要在小數點后面加零即可。最主要的是千分符的處理,好,就來說千分符。
千分符問題
數字千分符的處理有很多處理方案,最主要的有下面幾種。
方法一:循環遍歷
思路:
將數字轉換成字符串,然后倒序遍歷取值,每取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 )
options
options對象的屬性就有很多了,下面列舉一個常用的屬性。
style
: 默認為decimal
,表示十進制格式,currency
表示貨幣格式,percent
表示百分比格式。currency
: 如果style設置為currency,則該屬性設置貨幣符號(USD
表示美元,EUR
表示歐元, orCNY
是人民幣等等,更多符號參考鏈接: https://www.currency-iso.org/en/home/tables/table-a1.html )useGrouping
: 是否使用千分符,默認為trueminimumIntegerDigits
:設置整數最小位數(當整數位數不足時,在前面加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 查找相關內容,基本上用法都是類似的。
最后,如果看完有收獲,就動動小手點個贊再走唄,筆芯。