2011-02-04 52 views
4

我试图创建一个正则表达式来验证英国日期格式。我有以下几点:英国日期正则表达式

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

这个伟大的工程来验证:/12/2011但是如果日期是:/12/2011它不会正确验证。是否有一个正则表达式允许我在日节中使用单个数字和两个数字?例如“”和“”。

+1

@Martinho:我认为LooDaFunk表明正则表达式的一个很好的理解 - 他的正则表达式是有限的,但正确的。他被困在一个小细节上,这正是人们为何选择SO的原因。 – 2011-02-04 10:05:40

+0

@Tim:我很难相信有人能够自己想出来,至少不能拿出'([1-9] | 0 [1-9] | [12] [0-9 ] | 3 [01])[ - /.](0[1-9]|1[012])[-/。](19 | 20)\ d \ d`。但是,那么我可能是错的。 – 2011-02-04 10:09:43

+0

@Martinho:我很想在正则表达式深入学习,但我没有去学习每一件事情对他们再回来的时候,做我感觉像分离段的更重要的工作 – Funky 2011-02-04 10:13:40

回答

8

就取得领先0可选:

(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])[- /.](19|20)\d\d 

您将需要一个额外的验证步骤,但 - 此正则表达式当然不会检查无效的日期一样31-02-2000等,虽然有可能在做这个正则表达式,这是不推荐的,因为它以编程方式执行此操作更容易,并且该正则表达式将是可怕的。 Here is a date validating regex(虽然使用了mmddyyyy格式)来展示我的意思。

+0

无论如何这种方法不是很正确,49也应该匹配。 – 2011-02-04 10:00:41

0

是的。 {n,m}是说“至少有n个元素,最多m个元素”的量词。所以你可以写\d{1,2}(匹配1或2位数字)。完成日期:\d{1,2}/\d{1,2}/\d{4}

替代:使前导零可选:

0?\d/0?\d/\d{4} 

问号表示,该问号之前的元素是可选的。

0

检查当天的正确方法是禁止[4-9].号码。

喜欢的东西0[0-9]|[12][0-9]|3[01]|[^0-9][0-9]|^[0-9]

3

我偏爱去了简单的regex,(\d{1,2})[-/.](\d{1,2})[-/.](\d{4})的组合,与一些代码,证实这确实是一个正确的日期。无论如何,你必须拥有该代码,除非你想制作一个拒绝“29-02-2011”但不是“29-02-2008”的怪异正则表达式。

不管怎样,下面是正则表达式的崩溃,所以你可以看到发生了什么事情:

  • \d{1,2}:这部分匹配一个或两个({1,2})数字(\d),占该日期的天部分。
  • [-/.]:此相匹配的支架,即内部的字符之一,或者是.,一个/,或-
  • \d{1,2}:再一次,这匹配从一个月的一个或两个数字。
  • [-/.]:另一个分隔符...
  • \d{4}:这恰好与年份部分的四位({4})数字匹配。

请注意,正则表达式的日,月和年部分位于括号内。这是创建。这三部分中的每一部分都将被捕获到一个可以从比赛中检索出来的组中。组用一个数字标识,从1开始,从左到右。这意味着当天将是第1组,第2组和第3组。还有一个组0始终包含匹配的全部文本。

您可以使用组来执行验证的第二部分,并拒绝无效的日期,如“30-02-2011”,“31-4-2011”或“32-13-2011”。

如果你要拒绝使用两个不同的分隔符输入,如“31-12.2011”,你可以使用一个叫做反向引用一个更高级的功能:

(\d{1,2})([-/.])(\d{1,2})\2(\d{4}) 

需要注意的是,现在我把第一组内的分隔符。这将月份更改为组3,将年份更改为组4.分隔符与组2匹配。反向引用是月份和年份之间的\2部分。它匹配第二个前一组匹配的任何内容。如果从反向引用中退回两个组,则最终在组2中为分隔符。如果该组匹配.,则反向引用仅匹配.;如果它匹配-,则反向引用将仅匹配-;等等。

1

什么是“英国的日期格式”呢?

据官方统计,今天是2011-02-21,见BS EN 28601/ISO 8601

在网络上,你都应该使用RFC 3339

0

使用此代码中定义的格式,我正在验证日期的所有内容。 : -

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
public class FinalDateValidator { 

     private Pattern pattern; 
     private Matcher matcher; 

     public boolean isValidDate(final String date) { 
      Pattern pattern; 
      Matcher matcher; 
      final String DATE_PATTERN = "([0-9]{4})/(0?[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01]|[1-9])"; 
      pattern = Pattern.compile(DATE_PATTERN); 
      matcher = pattern.matcher(date); 
      if (matcher.matches()) { 
       matcher.reset(); 
       if (matcher.find()) { 
        int year = Integer.parseInt(matcher.group(1)); 
        String month = matcher.group(2); 
        String day = matcher.group(3); 

        System.out.println("__________________________________________________"); 
        System.out.println("year : "+year +" month : "+month +" day : "+day); 

        if (day.equals("31") 
          && (month.equals("4") || month.equals("6") 
            || month.equals("9") || month.equals("11") 
            || month.equals("04") || month.equals("06") || month 
            .equals("09"))) { 
         return false; // only 1,3,5,7,8,10,12 has 31 days 
        } else if (month.equals("2") || month.equals("02")) { 
         // leap year 
         if (year % 4 == 0) { 
          if (day.equals("30") || day.equals("31")) { 
           return false; 
          } else { 
           return true; 
          } 
         } else { 
          if (day.equals("29") || day.equals("30") 
            || day.equals("31")) { 
           return false; 
          } else { 
           return true; 
          } 
         } 
        } else { 
         return true; 
        } 
       } else { 
        return false; 
       } 
      } else { 
       return false; 
      } 
     } 

     public static void main(String argsp[]){ 

      FinalDateValidator vs = new FinalDateValidator(); 
     System.out.println("1: 1910/12/10---"+vs.isValidDate("1910/12/10")); 
      System.out.println("2: 2010/2/29---"+vs.isValidDate("2010/02/29")); 
      System.out.println("3: 2011/2/29---"+vs.isValidDate("2011/02/29")); 
      System.out.println("3: 2011/2/30---"+vs.isValidDate("2011/02/30")); 
      System.out.println("3: 2011/2/31---"+vs.isValidDate("2011/02/31")); 
      System.out.println("4: 2010/08/31---"+vs.isValidDate("2010/08/31")); 
      System.out.println("5: 2010/3/10---"+vs.isValidDate("2010/03/10")); 
      System.out.println("6: 2010/03/33---"+vs.isValidDate("2010/03/33")); 
      System.out.println("7: 2010/03/09---"+vs.isValidDate("2010/03/09")); 
      System.out.println("8: 2010/03/9---"+vs.isValidDate("2010/03/9")); 
      System.out.println("9: 1910/12/00---"+vs.isValidDate("1910/12/00")); 
      System.out.println("10: 2010/02/01---"+vs.isValidDate("2010/02/01")); 
      System.out.println("11: 2011/2/03---"+vs.isValidDate("2011/02/03")); 
      System.out.println("12: 2010/08/31---"+vs.isValidDate("2010/08/31")); 
      System.out.println("13: 2010/03/39---"+vs.isValidDate("2010/03/39")); 
      System.out.println("14: 201011/03/31---"+vs.isValidDate("201011/03/31")); 
      System.out.println("15: 2010/032/09---"+vs.isValidDate("2010/032/09")); 
      System.out.println("16: 2010/03/922---"+vs.isValidDate("2010/03/922")); 

     } 

    } 

享受...

0

我跑进了类似的要求。 这是完整的正则表达式以及闰年验证。 格式:DD/MM/YYYY

(3- [01] | [12] \ d | 0 [1-9])/(0 [13578] | 10 | 12)/((?0000)\ d {4})|(30 | [12] \ d | 0 [1-9])/(0 [469] | 11)/((?0000)\ d {4})|(2 [O- 8] | [01] \ d | 0 [1-9])/(02)/((?0000)\ d {4})| 29 /(02)/(1600 | 2000 | 2400 | 2800 | 00)| 29 /(02)/(\ d \ d)(0 [48] | [2468] [048] | [13579] [26] )

它可以很容易地修改,以美国的格式或其他格式的EU。