2011-02-04 106 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。