方法说明
@function Name: formatCurrency()
@param {number} value:
要格式化的数字@param {number} decimalPlaces:
小数位数(默认为2)@description:
该函数将数字转换为千分位格式,并保留指定的小数位数。- 如果输入值为
null、undefined
或空字符串,则返回原值。 - 若小数部分全为
0
,则不显示小数部分。
- 如果输入值为
// 转千分位格式
/**
* 格式化数字为千分位格式
* @param {number} value - 要格式化的数字
* @param {number} decimalPlaces - 小数位数(默认为2)
* @description 该函数将数字转换为千分位格式,并保留指定的小数位数。
* 如果输入值为null、undefined或空字符串,则返回原值。
* 若小数部分全为0,则不显示小数部分。
* @example
* formatCurrency(1234567.89) // 输出: '1,234,567.89'
* formatCurrency(0) // 输出: '0'
* formatCurrency(1234567.89, 0) // 输出: '1,234,568'
* @returns {string} 格式化后的字符串
*/
export const formatCurrency = (value, decimalPlaces = 2) => {
if (value == null || value === undefined || value === '') return value
const num = Number(value)
if (isNaN(num)) return value
if (num === 0) return '0'
// return value.replace(/\d(?=(\d{3})+\.)/g, '$&,')
const numStr = new Decimal(value).toFixed(decimalPlaces)
const parts = numStr.toString().split('.')
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
// 检查小数部分是否全为0
if (parts[1] && parts[1].replace(/0/g, '') === '') {
return parts[0] // 不显示小数部分
}
return parts.join('.')
}
正则说明
1. 正则\B
什么意思
在正则表达式中,\B
表示匹配非单词边界的位置。它与\b
(单词边界)相反。
具体解释:
-
\B
匹配这样的位置:- 前后都是单词字符(字母、数字、下划线)
- 前后都是非单词字符
-
在正则表达式
/\B(?=(\d{3})+(?!\d))/g
中:\B
确保匹配的位置不在单词边界(?=(\d{3})+(?!\d))
是正向预查,匹配后面跟着3的倍数个数字的位置- 组合起来就是:在数字内部(非边界)每3位插入一个逗号
示例:
"1234567".replace(/\B(?=(\d{3})+(?!\d))/g, ',')
// 结果: "1,234,567"
2. 正则?=
什么意思
在正则表达式中,?=
表示正向肯定预查(positive lookahead),属于零宽断言的一种。它用于匹配后面跟着特定模式的位置,但不会消耗字符(即匹配结果不包含预查的内容)。
在正则表达式 /\B(?=(\d{3})+(?!\d))/g
中:
?=(\d{3})+(?!\d)
表示:- 匹配一个位置,这个位置后面必须跟着:
(\d{3})+
:一组3位数字(\d表示数字),可以重复1次或多次(?!\d)
:且这组数字后面不能再跟数字(负向预查)
- 但匹配结果不包含这些数字本身
- 匹配一个位置,这个位置后面必须跟着:
组合起来的作用是:在每3位数字前的位置插入逗号(千分位分隔符),但:
\B
确保不在单词边界(避免在开头插入逗号)(?!\d)
确保不会在不足3位的位置插入逗号
示例:
"1234567".replace(/\B(?=(\d{3})+(?!\d))/g, ',')
// 匹配位置:1和234之间、4和567之间
// 结果: "1,234,567"