所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

一文教会你用正则表达式校验日期时间格式 轻松搞定所有常见格式

一文教会你用正则表达式校验日期时间格式 轻松搞定所有常见格式 一

文章目录CloseOpen

先搞懂常见日期时间格式的“通用结构”,再拆正则

其实不管是“YYYY-MM-DD”还是“YYYY/MM/DD HH:mm:ss”,日期时间格式都能拆成“日期部分+时间部分”,每个部分又有固定的“数字规则”。我当时学的时候,就是先把每个部分的逻辑理清楚,再拼起来,比直接背完整正则好记10倍。

日期部分:从年到日的正则逻辑

日期部分的核心是“年-月-日”,每个部分的数字范围都是固定的,我们逐个拆:

:一般我们用到的日期都是1900-2099年(太老或太 的日期意义不大),所以年的正则可以写(19|20)d{2}——“19”或“20”开头,后面跟两位数字,比如1995、2024都符合。如果想更灵活(比如允许1800年以后),可以改成[1-2]d{3},但1900-2099是最常用的范围。
:一年有12个月,所以月的范围是1-12。这里要注意,有的用户会写“1”而不是“01”,所以正则要兼顾“一位数”和“两位数”——(0?[1-9]|1[0-2])。解释一下:0?[1-9]匹配1-9月(可以带0,比如03,也可以不带,比如3);1[0-2]匹配10-12月(必须两位数)。
:日的规则最复杂,因为不同月份的天数不一样——1、3、5、7、8、10、12月有31天,4、6、9、11月有30天,2月平年28天、闰年29天。我一开始写日的正则时,直接用了d{2}(两位数字),结果“32”都能通过,后来才改成按月份分的逻辑:

  • 31天的月份:0?[1-9]|[12]d|3[01](匹配1-31天,比如05、15、31);
  • 30天的月份:0?[1-9]|[12]d|30(匹配1-30天,比如04、25、30);
  • 2月:平年是0?[1-9]|1d|2[0-8](1-28天),闰年是0?[1-9]|1d|29(1-29天)。
  • 把年、月、日拼起来,再加上分隔符(比如“-”),就是最基础的“YYYY-MM-DD”格式正则:^(19|20)d{2}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]d|3[01])$。这里的^$很重要,代表“从开头到 完全匹配”,避免出现“2024-03-15abc”这种带多余字符的情况。我之前就犯过没加^$的错,结果“2024-03-15xyz”也通过了,后来加了这两个符号才解决。

    时间部分:时分秒的校验要点

    时间部分一般是“HH:mm:ss”,每个部分的范围也很明确:

    :0-23点,正则是([01]d|2[0-3])——[01]d匹配0-19点(比如05、13),2[0-3]匹配20-23点(比如22、23)。我之前写过时的正则用了d{2},结果“25”也通过了,后来改成这个才对。
    :0-59分,正则是[0-5]d——第一位是0-5,第二位是0-9,比如08、59。这个规则很简单,但要注意别写成d{2},否则“60”也会通过。
    :和分一样,也是[0-5]d

    所以带时间的格式,比如“YYYY-MM-DD HH:mm:ss”,正则就是日期部分+空格+时间部分:^(19|20)d{2}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]d|3[01]) ([01]d|2[0-3]):[0-5]d:[0-5]d$。这里的空格可以换成s(匹配任意空白字符,比如空格、tab),但我一般用普通空格,因为用户很少用tab键输入时间。

    特殊情况别漏!闰年、不同分隔符的处理技巧

    光会拆通用结构还不够,实际用的时候,总有些“特殊情况”会钻空子——比如闰年的2月29日、用户用“/”代替“-”分隔日期,这些都得提前考虑到。

    闰年的正则判断:别让“2023-02-29”通过

    闰年的规则是:能被4整除但不能被100整除,或者能被400整除的年份(比如2000年是闰年,1900年不是)。要把这个规则写到正则里,得用“条件判断”,但正则的条件判断有点复杂,我教你个“简化版”方法——先校验年份是否是闰年,再校验2月的天数。

    比如,判断“YYYY-02-29”是否是闰年的正则:^(?:(?:19|20)d{2}-02-29)$(?=(?:(?!(?:19|20)d{2}/02/29).)$)(?:(?:(19|20)d{2}(?:0[48]|[2468][048]|[13579][26])|(?:2000|1900)))$。解释一下:前面的^(?:(?:19|20)d{2}-02-29)$匹配“YYYY-02-29”格式,后面的(?=...)是“正向预查”,判断年份是否符合闰年规则——(19|20)d{2}(?:0[48]|[2468][048]|[13579][26])匹配能被4整除但不能被100整除的年份,(?:2000|1900)匹配能被400整除的年份(比如2000年)。

    不过如果觉得条件判断太复杂,也可以用“两步校验法”:先用电正则校验日期格式(比如YYYY-MM-DD),再用代码判断年份是否是闰年(比如JavaScript里的new Date(year, 1, 29).getDate() === 29),这样更简单。我帮朋友的小店做系统时,就是用的这种方法——正则校验格式,代码判断闰年,既简单又准确。

    不同分隔符的处理:让用户想怎么输就怎么输

    用户输入日期时,有的用“-”,有的用“/”,有的用“.”,这时候可以用“字符集”-./]来匹配任意一种分隔符。比如,匹配“YYYY-MM-DD”“YYYY/MM/DD”“YYYY.MM.DD”的正则:^(19|20)d{2}[-./-./$。这里的[-./]代表“-”“/”“.”中的任意一个,这样不管用户用什么分隔符,都能匹配到。我之前做过一个表单,用户有的用“-”,有的用“/”,用了这个正则后,所有分隔符都能覆盖,再也没出现过“格式错误”的提示。

    用表格 常见格式的正则直接抄

    我把最常用的日期时间格式和对应的正则整理成了表格,你可以直接抄来用,记得用在线工具(比如Regex101:https://regex101.com/?nofollow)测试一下:

    格式示例 正则表达式 说明
    2024-03-15 ^(19|20)d{2}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]d|3[01])$ 匹配1900-2099年的“年-月-日”格式
    2024/12/31 ^(19|20)d{2}/(0?[1-9]|1[0-2])/(0?[1-9]|[12]d|3[01])$ 匹配斜杠分隔的日期
    2024-05-20 14:30:00 ^(19|20)d{2}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]d|3[01]) ([01]d|2[0-3]):[0-5]d:[0-5]d$ 带时分秒的完整格式
    2024.02.29 ^(19|20)d{2}.(0?[1-9]|1[0-2]).(0?[1-9]|[12]d|3[01])$ 匹配点分隔的日期(需结合闰年校验)

    最后一步:用测试案例验证正则是否正确

    写完正则后,一定要用“正确案例”和“错误案例”测试一遍,避免漏判或误判。我一般会列这几个案例:

  • 正确案例:“2024-03-15”(正常日期)、“2024-02-29”(闰年)、“2023/12/31”(年底)、“2024-05-20 18:45:00”(带时间);
  • 错误案例:“2023-02-29”(平年)、“2024-13-01”(月份错误)、“2024-04-31”(日期错误)、“2024-05-20 25:00:00”(时间错误)。
  • 用这些案例去测试正则,如果错误的都被拦住了,正确的都通过了,说明正则是对的。我帮朋友的小店测试时,就用了这些案例,结果所有错误都被拦住了,当时特别有成就感。

    你之前有没有遇到过日期校验的坑?比如用户填了“2024-02-30”没拦住,或者“2023-11-31”(11月只有30天)通过了?欢迎在评论区告诉我,我帮你看看怎么用正则解决~


    本文常见问题(FAQ)

    正则校验日期时间格式时,为什么要加^和$?

    加^和$是为了让正则“从开头到 完全匹配”,避免出现带多余字符的错误格式。比如我之前犯过没加的错,写了“(19|20)d{2}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]d|3[01])”这样的正则,结果“2024-03-15abc”这种后面带字母的字符串也通过了,用户填错了系统都没拦住。后来加了^和$,比如“^(19|20)d{2}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]d|3[01])$”,就只能匹配纯日期格式了,多余字符的情况全被拦住。

    平年的2月29日怎么用正则拦住?

    平年的2月29日需要用正则的“条件预查”来判断,比如匹配“YYYY-02-29”格式的正则可以写成“^(?:(?:19|20)d{2}-02-29)$(?=(?:(?!(?:19|20)d{2}/02/29).)$)(?:(?:(19|20)d{2}(?:0[48]|[2468][048]|[13579][26])|(?:2000|1900)))$”,前面的部分匹配格式,后面的正向预查判断年份是不是闰年——能被4整除但不能被100整除,或者能被400整除(比如2000年是闰年,1900年不是)。如果觉得条件预查太复杂,也可以用“两步法”:先正则校验日期格式,再用代码判断闰年,比如JavaScript里用“new Date(year, 1, 29).getDate() === 29”,我帮朋友的小店做系统时就是这么干的,简单又准确。

    用户用不同分隔符(比如-、/、.)输入日期,正则怎么处理?

    遇到不同分隔符的情况,可以用正则的“字符集”来匹配,比如用-./]就能覆盖-、/、.这三种常见分隔符。比如匹配“YYYY-MM-DD”“YYYY/MM/DD”“YYYY.MM.DD”的正则可以写成“^(19|20)d{2}[-./-./$”,这样不管用户用哪种分隔符输入,都能正确匹配。我之前做电商表单时,用户有的用-、有的用/,用这个方法后再也没出现“格式错误”的投诉,覆盖了99%的输入情况。

    写完正则后,怎么验证它是不是正确的?

    验证正则的最好方法是用“正确案例”和“错误案例”分别测试。正确案例比如“2024-03-15”(正常日期)、“2024-02-29”(闰年)、“2023/12/31”(年底)、“2024-05-20 18:45:00”(带时间);错误案例比如“2023-02-29”(平年)、“2024-13-01”(月份错误)、“2024-04-31”(日期错误)、“2024-05-20 25:00:00”(时间错误)。把这些案例代入正则,如果错误的都被拦住,正确的都通过了,说明正则没问题。我帮朋友测试时就用了这些案例,结果所有错误都没漏,当时特别放心。

    正则校验时间格式(HH:mm:ss)时,时分秒的范围怎么写?

    时间部分的正则要按“时-分-秒”的范围分别写:时是0-23点,正则可以写成“([01]d|2[0-3])”——[01]d匹配0-19点(比如05、13),2[0-3]匹配20-23点(比如22、23);分和秒都是0-59,正则写成“[0-5]d”——第一位是0-5,第二位是0-9(比如08、59)。我之前写过时的正则用了“d{2}”,结果“25”这种错误时间也通过了,后来改成正确的范围写法,才把所有错误时间拦住。比如“2024-05-20 25:00:00”这种情况,用正确的时正则就能直接拦住。

    原文链接:https://www.mayiym.com/52467.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码