使用正则表达式将数值转化为千分位格式

实现思路

拿到这个问题的时候先从最简单的入手,假如我们拿到的是一个四位数的整数,那么问题就变得好简单了。
首先要确认的一点是通过使用replace方法与平常有所不同
replace正常情况下是对字符串从前往后匹配
现在我们需要的是从后往前匹配,‘各十百千’是从后往前数的

于是乎就有了一下函数方法

技术方法

  1. 正则对象的 test() 方法
  2. 字符串的 replace() 方法

代码实现

function thousands(num) {
    
    
  // 转成 Number 类型
  num = +num
  // 判断是否是一个合法数
  if (isNaN(num)) {
    
    
    return '请传入一个合法数'
  }
  num = '' + num
  let [intNum, floatNum] = num.split('.')
  // 手动巧妙添加一个','标识符,方便循环匹配
  intNum += ','
  
  while (/\d{4}/.test(intNum)) {
    
    
    intNum = intNum.replace(/(\d{1})(\d{3}\,)/, '$1,$2')
  }
  // 删除我们刚刚添加的多余的 ','
  intNum = intNum.slice(0, -1)
  // 整数部分与小数部分拼接起来返回(小数部分做了判空)
  return intNum + (floatNum ? '.' + floatNum : '')
}

let s = '1234156567839.123'

console.log(thousands(s));
// 1,234,156,567,839.123

思考

既然循环使用replace实现,为什么不使用全局替换呢? 于是灵光乍现,就有了下面这种方法
function thousands(num) {
    
    
  // 转成 Number 类型
  num = +num
  // 判断是否是一个合法数
  if (isNaN(num)) {
    
    
    return '请传入一个合法数'
  }
  num = '' + num
  let [intNum, floatNum] = num.split('.')
  // 整数部分前后反转
  intNum = intNum.split('').reverse().join('')
  // 现在就是从前往后替换千分位的‘,’了
  intNum = intNum.replace(/\d{3}/g, '$&,')
  // 最后再反转回去
  intNum = intNum.split('').reverse().join('')

  // 上面三个部分当然可以简写成下面的一行,前提是: 如果你不怕你的同事打你的话 哈哈哈...
  // intNum = intNum.split('').reverse().join('').replace(/\d{3}/g, '$&,').split('').reverse().join('')

  // 整数长度为是三的倍数情况 去除第一个‘,’
  if (intNum[0] === ',' || intNum[1] === ',') {
    
    
    intNum = intNum.replace(',', '')
  }

  // 最后 整数 + 小数 返回 搞定!
  return intNum + (floatNum ? '.' + floatNum : '')
}

let s = '1234156567839.123'

console.log(thousands(s));
// 1,234,156,567,839.123

写在最后

最后,你可能比较好奇两种方式的执行效率上哪种更好呢? 比较了一下

  • 比较方式时间维度
console.time()
console.log(thousands(s));
console.timeEnd()
  • 前者
    default: 5.549ms, 5.643ms,6.109ms
  • 后者
    default: 6.486ms, 6.157ms, 5.466ms

结论

两者的效率旗鼓相当,从代码量上面和理解的难易程度上来看。个人更倾向与后者。

就补充这么多了,(厚着脸皮说)转载跟我说一下哈!

不对的地方也请指教,多谢!

补充:正则实现

如果使用正则来实现,那么…

replace(/\B(?=(\d{3})+(?!\d))/g, ",")

搞定!

猜你喜欢

转载自blog.csdn.net/qq_44900902/article/details/119843348