Regex para coincidir com a data

Quero corresponder datas com formato mm / dd / aa ou mm / dd / aaaa, mas não deve escolher 23/09/2010, em que o mês é 23, que é inválido, nem alguma data inválida como 00/12/2020 ou 12/00 / 2011

É melhor você dividir e testar todas as partes individuais. Mas se você realmente quiser usar um regex, você pode tentar este:

#\A(?:(?:(?:(?:0?[13578])|(1[02]))/31/(19|20)?\d\d)|(?:(?:(?:0?[13-9])|(?:1[0-2]))/(?:29|30)/(?:19|20)?\d\d)|(?:0?2/29/(?:19|20)(?:(?:[02468][048])|(?:[13579][26])))|(?:(?:(?:0?[1-9])|(?:1[0-2]))/(?:(?:0?[1-9])|(?:1\d)|(?:2[0-8]))/(?:19|20)?\d\d))\Z# 

Explicação:

 \A # start of string (?: # group without capture # that match 31st of month 1,3,5,7,8,10,12 (?: # group without capture (?: # group without capture (?: # group without capture 0? # number 0 optionnal [13578] # one digit either 1,3,5,7 or 8 ) # end group | # alternative (1[02]) # 1 followed by 0 or 2 ) # end group / # slash 31 # number 31 / # slash (19|20)? #numbers 19 or 20 optionnal \d\d # 2 digits from 00 to 99 ) # end group | (?:(?:(?:0?[13-9])|(?:1[0-2]))/(?:29|30)/(?:19|20)?\d\d) | (?:0?2/29/(?:19|20)(?:(?:[02468][048])|(?:[13579][26]))) | (?:(?:(?:0?[1-9])|(?:1[0-2]))/(?:(?:0?[1-9])|(?:1\d)|(?:2[0-8]))/(?:19|20)?\d\d) ) \Z 

Eu expliquei a primeira parte, deixando o resto como um exercício.

Esta correspondência é uma data inválida: 29/02/1900, mas está correta para quaisquer outras datas entre 01/01/1900 e 31/12/2099

Melhor que um enorme Regex louco (supondo que isso seja para validação e não para escaneamento):

 require 'date' def valid_date?( str, format="%m/%d/%Y" ) Date.strptime(str,format) rescue false end 

E como um editorial de lado: Eca! Por que você usaria um formato de data tão horrivelmente quebrado? Vá para ISO8601, YYYY-MM-DD , que é um padrão internacional válido, tem um ordenamento consistente de peças e classifica lexicograficamente também.

Ou você simplesmente usa Date.parse "some random date" .
Você obterá um ArgumentException se falhar a análise (=> a data é inválida).

Veja por exemplo http://santoro.tk/mirror/ruby-core/classs/Date.html#M000644

O melhor que você pode fazer com um regexp é validar o formato, por exemplo, algo como:

 [0-1][0-9]/[0-3][0-9]/[0-9]{2}(?:[0-9]{2})? 

Qualquer coisa além disso não pode ser feita de forma confiável sem algum tipo de dictionary de datas. A validade de uma data depende se é um ano bissexto ou não, por exemplo.

Para MM-DD-YYYY você pode usar a regex abaixo. Ele funcionará por anos bissextos e corresponderá às datas corretas apenas, a menos que o ano não exceda 2099.

 (?:(09|04|06|11)(\/|-|\.)(0[1-9]|[12]\d|30)(\/|-|\.)((?:19|20)\d\d))|(?:(01|03|05|07|08|10|12)(\/|-|\.)(0[1-9]|[12]\d|3[01])(\/|-|\.)((?:19|20)\d\d))|(?:02(\/|-|\.)(?:(?:(0[1-9]|1\d|2[0-8])(\/|-|\.)((?:19|20)\d\d))|(?:(29)(\/|-|\.)((?:(?:19|20)(?:04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96))|2000)))) 

O check-out corresponde em http://regexr.com/

então você quer um regex que irá corresponder como mm / dd / aa

 ^((0?1?1){1}|(0?1?2){1}|([0]?3|4|5|6|7|8|9))\/((0?1?2?3?1){1}|(0?1?2?(2|3|4|5|6|7|8|9|0))|(30))\/[1-90]{4}$ 

este regex irá corresponder exatamente o que você quer nesse formato mm / dd / aa um não irá validar qualquer data falsa você pode testar o regex em regex101 você pode testar para as datas 12/30/2040 e 09/09/2020 e o que nunca você quer para esse formato eu acho que este é também o regex mais curto que você pode encontrar para esse formato

Aqui está o código que você pode usar :), tente e me diga:

 ^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$