zoukankan      html  css  js  c++  java
  • 修正正则匹配日期---基于网络未知大神的正则

    今天工作时需要用到日期格式检验,于是发现未知的大神贡献的一套正则表达式【1】,看起来很复杂;

    但是经过测试发现有些问题:

    ((d{2}(([02468][048])|([13579][26]))[-/s]?((((0?[13578]
    )|(1[02]))[-/s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[4
    69])|(11))[-/s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[-/
    s]?((0?[1-9])|([1-2][0-9])))))|(d{2}(([02468][1235679])|([1
    3579][01345789]))[-/s]?((((0?[13578])|(1[02]))[-/s]?((
    0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[-/s]?((
    0?[1-9])|([1-2][0-9])|(30)))|(0?2[-/s]?((0?[1-9])|(1[0-9]
    )|(2[0-8]))))))

    经测试发现是存在一些问题的,如 1980-2-29只能匹配到1980-2-2,2100-2-29(非闰年)是会进入第一个闰年匹配的,这样就会出现闰年匹配和日期匹配不正确的情况。

    在此基础上,我做了一些修改,在此贴出:

    (((((([2468][048])|([13579][26]))00)|(d{2}((([2468][048])|([02468][48]))|([13579][26]))))
    [-/s]?((((1[02])|(0?[13578]))[-/s]?(([1-2][0-9])|(3[01])|(0?[1-9])))|(((11)|(0?[469]))
    [-/s]?(([1-2][0-9])|(30)|(0?[1-9])))|(0?2[-/s]?(([1-2][0-9])|(0?[1-9])))))
    |((((([2468][1235679])|([13579][01345789]))00)|(d{2}(([02468][1235679])|([13579][01345789]))))
    [-/s]?((((1[02])|(0?[13578]))[-/s]?(([1-2][0-9])|(3[01])|(0?[1-9])))|(((0?[469])|(11))
    [-/s]?(([1-2][0-9])|(30)|(0?[1-9])))|(0?2[-/s]?((1[0-9])|(2[0-8])|(0?[1-9]))))))

    下面对改动的正则分块做一下说明:

    1.匹配闰年:

    (((([2468][048])|([13579][26]))00)|(d{2}((([2468][048])|([02468][48]))|([13579][26]))))

    1.1 匹配可被400整除的年份

    ((([2468][048])|([13579][26]))00)

    1.2 匹配可被4整除但不能被100整除的年份

    (d{2}((([2468][048])|([02468][48]))|([13579][26])))

    1.3 注:经查阅 4的倍数有以下特征:(1):十位数为偶数时且个位是4的倍数的(含0),十位数为奇数且个位数为偶数且个位数字不是4的倍数; (2)十位和个位可被4整除则此数字即可被4整除;【2】

    2.匹配月日;需注意2月分的29号 和区别大小月份,1 3 5 7 8 10 12 这些是大月

    ((((1[02])|(0?[13578]))[-/s]?(([1-2][0-9])|(3[01])|(0?[1-9])))|(((11)|(0?[469]))[-/s]?(([1-2][0-9])|(30)|(0?[1-9])))|(0?2[-/s]?(([1-2][0-9])|(0?[1-9]))))

    2.1 解决02-29只匹配到02-2的问题

    改动前:(0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))
    改动后:([1-2][0-9])|(3[01])|(0?[1-9])))|(((11)|(0?[469]))

    由于未知的作者将最初将补零的验证置前,且0为匹配1次或0次,则匹配到[1-9]后不再进行 ‘或’ 后的匹配;

    3. 匹配平年

    (((([2468][1235679])|([13579][01345789]))00)|(d{2}(([02468][1235679])|([13579][01345789]))))

    3.1 匹配不能被4整除,但可以被100整除的年份;

    ((([2468][1235679])|([13579][01345789]))00)

    3.2 匹配既不能被4整除,又不能被100整除的年份;

    (d{2}(([02468][1235679])|([13579][01345789])))

    平年的月与闰年月只需注意区分2月即可

    经测试通过验证;

    如有不对,敬请指教

    原文链接:https://blog.icotools.cn/2019/07/23/%E6%AD%A3%E5%88%99%E5%8C%B9%E9%85%8D%E6%97%A5%E6%9C%9F%E6%97%B6%E9%97%B4/

    参考:

    【1】http://www.php230.com/1409454901.html 

    【2】https://www.zybang.com/question/61a275532cdfa6fe88b1360ed4ec6182.html

  • 相关阅读:
    (算法)最长重叠线段或区间
    (算法)判断两个区间是否重叠
    (笔试题)洗牌算法
    (笔试题)和一半的组合数
    (笔试题)删除K位数字
    (C语言)memcpy函数原型的实现
    每天坚持10分钟,改变你的人生
    你是哪种层次的程序员?程序员的四种类型
    2012年,软件开发者薪资大调查
    上班族:不要让自己成为老板的“日用品”!
  • 原文地址:https://www.cnblogs.com/nerd-gordon/p/7306272.html
Copyright © 2011-2022 走看看