需要正则表达式模式以将日期与可选时间匹配

我需要一个与日期和可选时间匹配的正则表达式模式。

日期应为m/d/yyyy格式的有效美国日期。 时间应该是h:mm:ss am/pm或24小时时间hh:mm:ss

比赛:2011年9月1日| 2011年9月1日上午10:00 | 9/1/2011 10:00 AM | 2011年9月1日10:00:00

这个模式将用于Ruby on Rails项目,因此它应该是可以通过Ruby使用的格式。 请参阅http://rubular.com/进行测试。

这是我现有的日期模式(可能是过度杀戮):

 DATE_PATTERN = /^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}/ 

正则表达式对于这种工作来说太可怕了。 如果您正在使用Ruby,我建议使用DateTime.strptime来解析数据并检查其有效性:

 def validate_date(date_str) valid_formats = ["%m/%d/%Y", "%m/%d/%Y %I:%M %P"] #see http://www.ruby-doc.org/core-1.9.3/Time.html#method-i-strftime for more valid_formats.each do |format| valid = Time.strptime(date_str, format) rescue false return true if valid end return false end 

嗯,这就是我最终的结果; 使用更严格的军事时间:

 DATE_TIME_FORMAT = /^([0,1]?\d{1})\/([0-2]?\d{1}|[3][0,1]{1})\/([1]{1}[9]{1}[9]{1}\d{1}|[2-9]{1}\d{3})\s([0]?\d|1\d|2[0-3]):([0-5]\d):([0-5]\d)$/ 

比赛:2011年1月19日23:59:59

捕获:

  1. 1
  2. 19
  3. 2011
  4. 23
  5. 59
  6. 59
 if subject =~ /\A(?:0?[1-9]|1[012])\/(?:0?[1-9]|[12]\d|3[01])\/(?:\d{4})(?:\s+(?:(?:[01]?\d|2[0-3]):(?:[0-5]\d)|(?:0?\d|1[0-2]):(?:[0-5]\d)\s+[ap]m))?\s*\Z/i # Successful match 

祝好运..

这个怎么运作 :

  " ^ # Assert position at the beginning of the string (?: # Match the regular expression below # Match either the regular expression below (attempting the next alternative only if this one fails) 0 # Match the character “0” literally ? # Between zero and one times, as many times as possible, giving back as needed (greedy) [1-9] # Match a single character in the range between “1” and “9” | # Or match regular expression number 2 below (the entire group fails if this one fails to match) 1 # Match the character “1” literally [012] # Match a single character present in the list “012” ) / # Match the character “/” literally (?: # Match the regular expression below # Match either the regular expression below (attempting the next alternative only if this one fails) 0 # Match the character “0” literally ? # Between zero and one times, as many times as possible, giving back as needed (greedy) [1-9] # Match a single character in the range between “1” and “9” | # Or match regular expression number 2 below (attempting the next alternative only if this one fails) [12] # Match a single character present in the list “12” \d # Match a single digit 0..9 | # Or match regular expression number 3 below (the entire group fails if this one fails to match) 3 # Match the character “3” literally [01] # Match a single character present in the list “01” ) / # Match the character “/” literally (?: # Match the regular expression below \d # Match a single digit 0..9 {4} # Exactly 4 times ) (?: # Match the regular expression below \s # Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) + # Between one and unlimited times, as many times as possible, giving back as needed (greedy) (?: # Match the regular expression below # Match either the regular expression below (attempting the next alternative only if this one fails) (?: # Match the regular expression below # Match either the regular expression below (attempting the next alternative only if this one fails) [01] # Match a single character present in the list “01” ? # Between zero and one times, as many times as possible, giving back as needed (greedy) \d # Match a single digit 0..9 | # Or match regular expression number 2 below (the entire group fails if this one fails to match) 2 # Match the character “2” literally [0-3] # Match a single character in the range between “0” and “3” ) : # Match the character “:” literally (?: # Match the regular expression below [0-5] # Match a single character in the range between “0” and “5” \d # Match a single digit 0..9 ) | # Or match regular expression number 2 below (the entire group fails if this one fails to match) (?: # Match the regular expression below # Match either the regular expression below (attempting the next alternative only if this one fails) 0 # Match the character “0” literally ? # Between zero and one times, as many times as possible, giving back as needed (greedy) \d # Match a single digit 0..9 | # Or match regular expression number 2 below (the entire group fails if this one fails to match) 1 # Match the character “1” literally [0-2] # Match a single character in the range between “0” and “2” ) : # Match the character “:” literally (?: # Match the regular expression below [0-5] # Match a single character in the range between “0” and “5” \d # Match a single digit 0..9 ) \s # Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) + # Between one and unlimited times, as many times as possible, giving back as needed (greedy) [ap] # Match a single character present in the list “ap” m # Match the character “m” literally ) )? # Between zero and one times, as many times as possible, giving back as needed (greedy) \s # Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) * # Between zero and unlimited times, as many times as possible, giving back as needed (greedy) $ # Assert position at the end of the string (or before the line break at the end of the string, if any) " 

记住,不是你的勺子!

以下是我提出的似乎有效的方法:
regex = /^1?\d{1}\/[123]?\d{1}\/\d{4}(\s[12]?\d:[0-5]\d(:[0-5]\d)?(\s[ap]m)?)?$/