加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式在日期处理的一个应用

发布时间:2020-12-14 06:35:35 所属栏目:百科 来源:网络整理
导读:最近在翻看原来写的工具函数中,发现了 formatDate 这个工具函数,原来只是在使用,具体的实现原理没有仔细研究过,这次就来分析一下它的实现,了解一下正则表达式的一个实战应用。 函数功能 formatDate 函数接受两个参数,日期对象和格式参数,可以根据不同

最近在翻看原来写的工具函数中,发现了formatDate这个工具函数,原来只是在使用,具体的实现原理没有仔细研究过,这次就来分析一下它的实现,了解一下正则表达式的一个实战应用。

函数功能

formatDate 函数接受两个参数,日期对象和格式参数,可以根据不同的格式参数将事件对象转换成日期格式,大致使用如下

formatDate(new Date(),'yy-mm-dd')    // 18-05-13
formatDate(new Date(),'yyyy-MM-dd hh:mm') // "2018-05-13 16:35"

当然也可以把函数挂载在prototype上面,这样就只需要一个参数了,这个后续再说。

实现思路

实现思路比较简单,就是利用,Date提供的函数,比如getMonthgetFullYear等函数先把Date对象拆解出必要的部分。年月日小时分钟秒等,然后再根据传入的参数进行组合,得到想要的效果。这里有几个处理过程中需要注意的地方。

  • 对于1位的数字应该可以支持选择补0也可以不补0
formatDate(new Date(),'yyyy-M-dd') // "2018-5-13"
formatDate(new Date(),'yyyy-MM-dd') // "2018-05-13"
  • 对于月份因为是从0开始计数的,所以要+1月,不是加1s啊
  • 支持参数的各种组合

实现过程

因为需要支持各种组合,所以需要一个对象将个部分存储下来,根据参数的格式能够快速的解析出来对应的值。对象的格式大致如下

var cfg = {
    yyyy: date.getFullYear(),// 年 : 4位
    yy: date.getFullYear().toString().substring(2),// 年 : 2位
    M: date.getMonth() + 1,// 月 : 如果1位的时候不补0
    MM: paddNum(date.getMonth() + 1),// 月 : 如果1位的时候补0
    d: date.getDate(),// 日 : 如果1位的时候不补0
    dd: paddNum(date.getDate()),// 日 : 如果1位的时候补0
    hh: paddNum(date.getHours()),// 时
    mm: paddNum(date.getMinutes()),// 分
    ss: paddNum(date.getSeconds()) // 秒
  }

双位补0单位不补0,补0的过程封装成一个函数paddNum,自然想到的是用正则表达式来判断是否是1位,很容易写出如下代码

let paddNum = num => {
  if (/^d$/.test(num)) {
     return '0' + num
  }
  return num
}

不过还可以使用字符串提供的正则表达式replace功能简化这个过程,使用捕获组来获取匹配的值,再+0,如果没有匹配,就返回本身,这也正是我们想要的,这里提前需要把数字转换成字符串。

let paddNum = num => num.toString().replace(/^(d)$/,'0$1')

这样每个日期的数据处理部分就做完了。
下面实现日期格式的解析,要把传入的日期格式做匹配,然后从对象解析出对应的值,再拼到一块。
分析传入日期的格式,都是yyyydd这种重叠的格式,这就需要针对每一个匹配出来的值,都要匹配到与其相同的一组值,也就是如果匹配到y,那就要把紧跟在y后面所有的y都匹配出来,比如yyyyyy等,直到遇到首个不是y的字符停止。这就需要在匹配环节记住匹配的部分并重复匹配,捕获组又派上了用场。 /([a-z])(1)*/1可以代替匹配到的字符,进而组成新的匹配条件,这样的匹配条件就是那种想要的重叠格式了。
所以解析的过程如下

format.replace(/([a-z])(1)*/ig,m => cfg[m])

整合

稍作整理,这个工具函数就组合起来了

const formatDate = (date=new Date(),format='yyyy-MM-dd hh:mm:ss') => {
  // 单位补0
  let paddNum = num => num.toString().replace(/^(d)$/,'0$1')
  // 指定格式字符
  var cfg = {
    yyyy: date.getFullYear(),// 日 : 如果1位的时候补0
    h: date.getHours(),// 时
    hh: paddNum(date.getHours()),// 分
    ss: paddNum(date.getSeconds()) // 秒
  }
  return format.replace(/([a-z])(1)*/ig,m => cfg[m])
}

可以看出用好正则表达式的捕获组,可以大大简化代码量,逻辑看上去也很清楚。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读