正则表达式验证日期格式dd/mm/yyyy

Nal*_*526 146 regex

我需要dd/mm/yyyy使用常规表达来验证格式的日期字符串.

此正则表达式验证dd/mm/yyyy,但不是无效日期,如31/02/4500:

^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$
Run Code Online (Sandbox Code Playgroud)

dd/mm/yyyy使用闰年支持验证格式的有效正则表达式是什么?

Ofi*_*zon 292

您粘贴的正则表达式不能正确验证闰年,但在同一篇文章中有一个.我修改它采取dd/mm/yyyy,dd-mm-yyyydd.mm.yyyy.

^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

我在他的答案中提供的Arun链接中测试了一下它也在这里它似乎工作.

编辑2019年2月14日:我删除了正则表达式中允许日期的逗号 29-0,-11

  • 史诗正则表达!根据格式可以轻易地互换?例如yyyy-mm-dd和mm-dd-yyyy.我考虑到了这一点,但它超出了我的正则表达能力. (6认同)
  • 除了'DD/MM/YYYY`之外,这个正则表达式也接受'DD/MM/YY`,我不确定它是否是海报的初衷.如果你不支持'YY',那么删除所有可选的`?`量词. (6认同)
  • @MaraisRossouw,你是对的,对于4位数的年份,实际上有3个```应该被删除:用`替换所有`(?:1 [6-9] | [2-9]\d)?` ?:1 [6-9] | [2-9]\d)`. (4认同)
  • 顺便说一句:**哇**,当然_谢谢你_ (3认同)
  • @purveshdesai,删除最后一次出现的`?` (2认同)
  • @PurveshDesai用'0`替换每个'0?`,并删除最后一次出现的`?`. (2认同)

Alo*_*ary 245

我根据我的要求扩展了@Ofir Luzon给出的格式dd-mmm-YYYY,dd/mmm/YYYY,dd.mmm.YYYY的正则表达式.其他有相同要求的人可以参考

^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
Run Code Online (Sandbox Code Playgroud)

并在http://regexr.com/39tr1上测试了一些测试用例.

为了更好地理解此正则表达式,请参考此图像: 在此输入图像描述

  • 为图像投票.:)你是如何产生它的? (31认同)
  • @ user3733831`8888'可能是一年。我希望活到那个年龄。 (4认同)
  • @AlokChaudhary,该图是使用 https://www.debuggex.com 生成的 (3认同)
  • 是的,你是怎么生成的?:) (2认同)

gdZ*_*eus 64

注意:

你的正则表达式在"4和100的倍数,但不是400的倍数"的数年内不起作用.通过该测试的年数不是闰年.例如:1900,2100,2200,2300,2500等.换句话说,它将格式\ d\d00的所有年份放在同一类闰年中,这是不正确的. - MuchToLearn

所以它只适用于[1901 - 2099](Whew)

DD/MM/YYYY:

检查闰年.从1900年到9999年是有效的.只有dd/MM/yyyy

(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)
Run Code Online (Sandbox Code Playgroud)

  • 这个答案与dd/MM/yyyy一起_only_.因此,是正确的答案. (6认同)
  • 例如,如果您有19/05/2014,则不起作用. (3认同)
  • @SylvainB我修好了 (2认同)
  • @gdZeus 感谢您的交付,即使是两年后!可怕的是,一个不完整的解决方案已经在这里验证了这么长时间。 (2认同)

A.T*_*.T. 13

试试这个.

^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$
Run Code Online (Sandbox Code Playgroud)

您可以轻松地在http://www.regular-expressions.info/javascriptexample.html上测试正则表达式.

  • 这个正则表达式不会像`30-02-2001`这样的月份来验证日期......无论如何感谢你的回答:) (2认同)

Jas*_*nya 11

我怀疑在不知道用户的区域设置何时从Julian切换到Gregorian日历时,以下内容与预期的一样准确.

无论顺序如何,它都接受" - ","/",或者在年,月和日之间不作为分隔符.

MMDDYYYY:

^(((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))[-/]?[0-9]{4}|02[-/]?29[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$
Run Code Online (Sandbox Code Playgroud)

DDMMYYYY:

^(((0[1-9]|[12][0-9]|30)[-/]?(0[13-9]|1[012])|31[-/]?(0[13578]|1[02])|(0[1-9]|1[0-9]|2[0-8])[-/]?02)[-/]?[0-9]{4}|29[-/]?02[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$
Run Code Online (Sandbox Code Playgroud)

YYYYMMDD:

^([0-9]{4}[-/]?((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))|([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00)[-/]?02[-/]?29)$
Run Code Online (Sandbox Code Playgroud)

除了秩序之外,这些都是精确到朱利安历法(闰年每四年)直到1700年,当格里高利历从朱利安出发时.它有两个问题:

  1. 它接受0000年,这在许多但并非所有标准中都不存在.请注意,ISO 8601确实接受0000年(相当于1 BCE).
  2. 它不会跳过格里高利历开始使用时丢失的10-13天.但这因地而异.例如,罗马天主教会在10月5日至1582年10月14日期间跳过了10天,但希腊(最后一次转换)跳过了2月16日到1923年的28日,13天,不得不考虑到1700年的闰年, 1800年和1900年.

从1988年到9999年,已经对Java的日历实施进行了测试,唯一的差异是1582年的上述10天.


Luk*_*nga 10

对于那些看过这些并且完全混淆的人来说,这是我脚本的摘录.不幸的是,它只是在日期时间输入中匹配有效数字,并且2月31日将被标记为有效,但正如许多人所说,正则表达式确实不是进行此测试的最佳工具.

要匹配"yyyy-MM-dd hh:mm"格式的日期(或者确实以任何顺序)

var dateerrors = false;
var yearReg = '(201[4-9]|202[0-9])';            ///< Allows a number between 2014 and 2029
var monthReg = '(0[1-9]|1[0-2])';               ///< Allows a number between 00 and 12
var dayReg = '(0[1-9]|1[0-9]|2[0-9]|3[0-1])';   ///< Allows a number between 00 and 31
var hourReg = '([0-1][0-9]|2[0-3])';            ///< Allows a number between 00 and 24
var minReg = '([0-5][0-9])';                    ///< Allows a number between 00 and 59
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
$('input').filter(function () {return this.id.match(/myhtml_element_with_id_\d+_datetime/);}).each(function (e) {
    if (e > 0) {
        // Don't test the first input. This will use the default
        var val = $(this).val();
        if (val && !val.trim().match(reg)) {
            dateerrors = true;
            return false;
        }
    }
});
if (dateerrors) {
    alert('You must enter a validate date in the format "yyyy-mm-dd HH:MM", e.g. 2019-12-31 19:30');
    return false;
}
Run Code Online (Sandbox Code Playgroud)

上面的脚本从构建一个正则表达式对象开始.然后它会找到id与特定模式匹配的所有输入,然后遍历这些输入.我没有测试我发现的第一个输入(if (e > 0)).

一点解释:

var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
Run Code Online (Sandbox Code Playgroud)

^表示匹配开始,而$表示匹配结束.

return this.id.match(/myhtml_element_with_id_\d+_datetime/);
Run Code Online (Sandbox Code Playgroud)

\d+装置匹配单个或整体的连续序列,所以myhtml_element_with_id_56_datetimemyhtml_element_with_id_2_datetime将匹配,但myhtml_element_with_id_5a_datetime不会


小智 9

year  = ((20[012]\d|19\d\d)|(1\d|2[0123])) 
month = ((0[0-9])|(1[012]))
day   = ((0[1-9])|([12][0-9])|(3[01]))

year-month-day = (((20[012]\d|19\d\d)|(1\d|2[0123]))-((0[0-9])|(1[012]))-((0[1-9])|([12][0-9])|(3[01])))
day-month-year = (((0[1-9])|([12][0-9])|(3[01]))-((0[0-9])|(1[012]))-((20[012]\d|19\d\d)|(1\d|2[0123])))
year/month/day = (((20[012]\d|19\d\d)|(1\d|2[0123]))\/((0[0-9])|(1[012]))\/((0[1-9])|([12][0-9])|(3[01])))
month/day/year = (((0[0-9])|(1[012]))\/((0[1-9])|([12][0-9])|(3[01]))\/((20[012]\d|19\d\d)|(1\d|2[0123])))
day/month/year = (((0[1-9])|([12][0-9])|(3[01]))\/((0[0-9])|(1[012]))\/((20[012]\d|19\d\d)|(1\d|2[0123])))
day.month.year = (((0[1-9])|([12][0-9])|(3[01]))\.((0[0-9])|(1[012]))\.((20[012]\d|19\d\d)|(1\d|2[0123])))
year.month.day = (((20[012]\d|19\d\d)|(1\d|2[0123]))\.((0[0-9])|(1[012]))\.((0[1-9])|([12][0-9])|(3[01])))


all = (((20[012]\d|19\d\d)|(1\d|2[0123]))-((0[0-9])|(1[012]))-((0[1-9])|([12][0-9])|(3[01])))|(((0[1-9])|([12][0-9])|(3[01]))-((0[0-9])|(1[012]))-((20[012]\d|19\d\d)|(1\d|2[0123])))|(((20[012]\d|19\d\d)|(1\d|2[0123]))\/((0[0-9])|(1[012]))\/((0[1-9])|([12][0-9])|(3[01])))|(((0[0-9])|(1[012]))\/((0[1-9])|([12][0-9])|(3[01]))\/((20[012]\d|19\d\d)|(1\d|2[0123])))|(((0[1-9])|([12][0-9])|(3[01]))\/((0[0-9])|(1[012]))\/((20[012]\d|19\d\d)|(1\d|2[0123])))|(((0[1-9])|([12][0-9])|(3[01]))\.((0[0-9])|(1[012]))\.((20[012]\d|19\d\d)|(1\d|2[0123])))|(((20[012]\d|19\d\d)|(1\d|2[0123]))\.((0[0-9])|(1[012]))\.((0[1-9])|([12][0-9])|(3[01])))

Run Code Online (Sandbox Code Playgroud)

它的工作是为了

yyyy-mm-dd
dd-mm-yyyy
yyyy/mm/dd
mm/dd/yyyy
dd/mm/yyyy
dd.mm.yyyy
yyyy.mm.dd

yy-mm-dd
dd-mm-yy
yyyy/mm/dd
mm/dd/yy
dd/mm/yy
dd.mm.yy
yy.mm.dd

Run Code Online (Sandbox Code Playgroud)

但不适用于 day =d或 Month =的情况m,例如 dmyyyy

所有示例 -在此处输入链接描述


Sim*_*ion 8

这是另一个正则表达式版本,可以匹配以下任何日期格式,并允许省略前导零:

正则表达式: ^[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}$

火柴:

1/1/11 or 1.1.11 or 1-1-11 : true 01/01/11 or 01.01.11 or 01-01-11 : true 01/01/2011 or 01.01.2011 or 01-01-2011 : true 01/1/2011 or 01.1.2011 or 01-1-2011 : true 1/11/2011 or 1.11.2011 or 1-11-2011 : true 1/11/11 or 1.11.11 or 1-11-11 : true 11/1/11 or 11.1.11 or 11-1-11 : true

正则表达式可视化

Debuggex演示

  • 如果你有'13/13/2000` =*匹配*是*真*不起作用* (3认同)
  • 39/39/39不是约会对象.请停止投票给出这个答案. (3认同)

Jon*_*y 5 7

在这里,我为dd/mm/yyyy分隔符可以是-.,/年份范围之一写了一个0000-9999

它处理闰年,专为正则表达式风格而设计,支持前瞻、捕获组和反向引用。不适用于诸如d/m/yyyy. 如果需要,请添加更多分隔符[-.,/]

^(?=\d{2}([-.,\/])\d{2}\1\d{4}$)(?:0[1-9]|1\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\d{4}$
Run Code Online (Sandbox Code Playgroud)

在 regex101 测试;作为 Java 字符串:

"^(?=\\d{2}([-.,\\/])\\d{2}\\1\\d{4}$)(?:0[1-9]|1\\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\\d{4}$"
Run Code Online (Sandbox Code Playgroud)

解释:

(?x) # modifier x: free spacing mode (for comments)
     # verify date dd/mm/yyyy; possible separators: -.,/
     # valid year range: 0000-9999

^    # start anchor

# precheck xx-xx-xxxx,... add new separators here
(?=\d{2}([-.,\/])\d{2}\1\d{4}$)

(?:  # day-check: non caturing group

  # days 01-28
  0[1-9]|1\d|[2][0-8]| 

  # february 29d check for leap year: all 4y / 00 years: only each 400
  # 0400,0800,1200,1600,2000,...
  29
  (?!.02. # not if feb: if not ...
    (?!
      # 00 years: exclude !0 %400 years
      (?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)

      # 00,04,08,12,... 
      \d{2}(?:[02468][048]|[13579][26])
    )
  )|

  # d30 negative lookahead: february cannot have 30 days
  30(?!.02)|

  # d31 positive lookahead: month up to 31 days
  31(?=.(?:0[13578]|10|12))

) # eof day-check

# month 01-12
.(?:0[1-9]|1[012])

# year 0000-9999
.\d{4}

$ # end anchor
Run Code Online (Sandbox Code Playgroud)

另请参阅SO Regex 常见问题解答;如果失败,请告诉我。


Nal*_*526 5

在这里找到这个注册

^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$
Run Code Online (Sandbox Code Playgroud)

这样mm/dd/yyyy可以正确验证格式和有效日期(但不能m/d/yyyy).

一些测试


use*_*114 5

"^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\\d\\d)$"
Run Code Online (Sandbox Code Playgroud)

将验证之间的任何日期 1900-2099


小智 5

以下表达式很好且易于操作:

((((0[13578]|1[02])(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)((\/|-|.)(0[1-9]|1[0-9]|2[0-8]))))(\/|-|.)(19([6-9][0-9])|20(0[0-9]|1[0-4])))|((02)(\/|-|.)(29)(\/|-|.)(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26])))
Run Code Online (Sandbox Code Playgroud)

它根据 MM/dd/YYYY 格式进行验证,并允许从 1960 年到 2016 年支持闰年。如果您需要扩展闰年支持,则只需操作表达式的这一部分:

(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]))
Run Code Online (Sandbox Code Playgroud)

希望这对你有很大帮助