Я хочу сопоставить даты с форматом mm/dd/yy или mm/dd/yyyy, но он не должен выбирать 23/09/2010, где месяц 23, который недействителен, а также некорректная дата, например 00/12/2020 или 12/00/2011.
Регулярное выражение для соответствия дате
Ответ 1
Лучше сделать раскол на/и проверить все отдельные части. Но если вы действительно хотите использовать регулярное выражение, вы можете попробовать следующее:
#\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#
Пояснение:
\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
Я объяснил первую часть, оставив остальное как упражнение.
Это соответствует одной неверной дате: 02/29/1900, но подходит для любых других дат между 01/01/1900 и 12/31/2099
Ответ 2
Лучше, чем сумасшедшее огромное Regex (предполагая, что это для проверки, а не сканирования):
require 'date'
def valid_date?( str, format="%m/%d/%Y" )
Date.strptime(str,format) rescue false
end
И как редакционная статья в сторону: Eww! Зачем вам использовать такой ужасно разбитый формат даты? Идите для ISO8601, YYYY-MM-DD
, который является действующим международным стандартом, имеет последовательный порядок частей и также сортирует лексикографически.
Ответ 3
Или просто используйте Date.parse "some random date"
.
Вы получите исключение ArgumentException, если он не выполнит парсинг (= > Дата недействительна).
См. http://santoro.tk/mirror/ruby-core/classes/Date.html#M000644
Ответ 4
Лучшее, что вы можете сделать с помощью регулярного выражения, - это проверка формата, например. что-то вроде:
[0-1][0-9]/[0-3][0-9]/[0-9]{2}(?:[0-9]{2})?
Все, что над этим невозможно сделать, невозможно сделать без какого-либо словарного словаря. Срок действия зависит от того, является ли он високосным годом или нет, например.
Ответ 5
Для MM-DD-YYYY
вы можете использовать следующее регулярное выражение. Он будет работать в течение високосных лет и будет соответствовать правильным датам, если только год не превысит 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))))
Оформить заказ в http://regexr.com/
Ответ 6
чтобы вы хотели, чтобы регулярное выражение соответствовало значению mm/dd/yy
^((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}$
это регулярное выражение будет соответствовать именно тому, что вы хотите в этом формате. mm/dd/yy a не будет проверять фальшивую дату, вы можете проверить регулярное выражение на regex101 вы можете проверить даты 12/30/2040 и 09/09/2020 и что вы хотите для этого формата, я думаю, что это также кратчайшее регулярное выражение, которое вы можете найти для этого формата.