js将字符串格式化为字符串形式的数字(允许负数)

将输入的字符串格式化为金额字符串


本人在制作 金额输入框时,由于数字数字框的右侧按钮难处理,所以使用文本输入框接收金额数字,这个函数是用来格式化与校验金额输入.

代码还不够优雅,望指点


/**
 * 将字符串格式为一个合规的字符串数字
 * @param {string} value 字符串大概率是数字字符串
 * @param {boolean} negative 是否允许负数
 * @param {boolean} last 是否是最后一次格式化,为了将'2.'格式化为'2.0'
 * @return {string} "999999999.99"
 */
export function strFormatStrNum(value, negative = false, last = false) {
  // 初始检测最容易出错与出现的值
  if (value === '0' || value === '.') {
    // 直接返回0
    return '0'
  } else if (negative) {
    // 初始输入有可能输入0-或者符号需要初始化
    if (value === '0-' || value === '-') {
      // 归零 注意js中有负数零存在
      return '-0'
    }
  }
  // -9代表数字上限为亿位数,-8代表数字上限为千万位数,-2代表数字上限为十位数,想要加大上限就加深负数
  const accuracy_upper_limit = -9
  // 2代表数字只保留小数点后两位
  const accuracy_lower_limit = 2
  // 需要返回的是负数
  const if_negative = negative && value.charAt(0) === '-'
  // 需要带上小数点
  const if_need_decimal_point = accuracy_lower_limit > 0 && value.indexOf('.') !== -1

  // 声明切割值保存的数组
  let parts = []
  /*
   * 将value切割成指定格式的字符串数组
   * 有可能输入的值不是字符串形式所以需要toString
   * e也会被判断为数字所以需要删除e
   * 0b判断为二进制数字删除b
   * 0o判断为八进制数字删除o
   * 0x判断为十六进制数字删除x
   * 默认清除负数所以也要删除-
   * split('.')切割为数组
   */
  parts = value
    .toString()
    .replace(/e/g, '')
    .replace(/b/g, '')
    .replace(/o/g, '')
    .replace(/x/g, '')
    .replace(/-/g, '')
    .split('.')

  // 内部函数定义数值初始化
  function strInit() {
    if (if_negative) {
      // -0 === 0 返回 true
      return '-0'
    } else {
      return '0'
    }
  }

  // 进行上限切割后数字化转化
  const int = Number(parts[0].slice(accuracy_upper_limit))

  // 获取整形部分
  function getStrInt() {
    // 需要返回负数的话,需要加回负号
    return if_negative ? '-' + String(int) : String(int)
  }

  // 是否有小数,小数数组长度为2,如果不需要小数那就只对整数判断
  if (parts.length === 1 || accuracy_lower_limit === 0) {
    // 整数情况
    // 数字化的结果有可能是非数值
    if (Number.isNaN(int)) {
      // 初始化
      return strInit()
    } else {
      // 数字化后不是NaN转回字符串
      return getStrInt()
    }
  } else {
    // 有小数情况
    // 切割出指定位数小数
    const decimal = parts[1].slice(0, accuracy_lower_limit)
    // 小数单独进行数字化
    // const double = Number(decimal)
    const regex = /^\d+$/
    // 判断是否有一边数字为NaN
    // !Number.isNaN(int) && !Number.isNaN(double)
    if (!Number.isNaN(int) && regex.test(decimal)) {
      // 两边的数字都不为NaN
      // 右边不使用double是要考虑到.01的这种情况,.01会转为1
      // 2024-06-13修改,由于之前没有考虑到小数后输入字母现在加上正则,regex只允许0-9
      return getStrInt() + '.' + decimal
    } else if (!Number.isNaN(int)) {
      // 只有整数部分是正常的话,不加.会导致用户无法输入小数
      // 2024-06-13修改,之前的三元表达式由于字符串连接 (+) 运算符的优先级高于比较运算符导致没有正确执行,现在加上括号提权
      // 2024-06-14修改,按之前的写法'2.0'中的.0无法被删除掉,所以需要允许'2.在输入框的存在'
      const value = getStrInt()
      if (if_need_decimal_point) {
        return value + (last ? '.0' : '.')
      } else {
        return value
      }
    } else {
      // 初始化
      return strInit()
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值