快速入門
教學
工具和語言
範例
參考
書籍評論
範例
正規表示式範例
數字範圍
浮點數
電子郵件地址
IP 位址
有效日期
數字日期轉換為文字
信用卡號碼
符合完整行
刪除重複行
程式設計
兩個相近的字詞
陷阱
災難性的回溯
過多重複
阻斷服務
讓所有內容都是選項
重複擷取群組
混合 Unicode 和 8 位元
本網站的更多資訊
簡介
正規表示式快速入門
正規表示式教學
替換字串教學
應用程式和語言
正規表示式範例
正規表示式參考
替換字串參考
書籍評論
可列印 PDF
關於本網站
RSS 摘要和部落格
RegexMagic—Generate regular expressions matching dates and times

符合有效日期的正規表示式

^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$ 符合從 1900-01-01 到 2099-12-31,且有四個分隔符號選擇的 yyyy-mm-dd 格式日期。錨點可確保整個變數是一個日期,而不是包含日期的文字片段。年份由 (19|20)\d\d 符合。我使用 交替 來允許前兩個數字為 19 或 20。括號是強制性的。如果我省略它們,正規表示式引擎會尋找 19 或正規表示式的其餘部分,這會符合介於 2000-01-01 和 2099-12-31 之間的日期。括號是唯一能阻止垂直線將整個正規表示式分成兩個選項的方法。

月份由 0[1-9]|1[012] 匹配,再次用括號包起來以保持兩個選項在一起。透過使用 字元類別,第一個選項會匹配 01 到 09 之間的數字,而第二個選項會匹配 10、11 或 12。

正規表示式的最後一部分包含三個選項。第一個選項會匹配 01 到 09 之間的數字,第二個選項會匹配 10 到 29 之間的數字,而第三個選項會匹配 30 或 31。

巧妙地使用交替讓我們可以排除無效的日期,例如 2000-00-00,而不用交替就無法排除。要做到真正完美,您必須將月份拆分成不同的選項,以考量月份的長度。上述正規表示式仍然會匹配 2003-02-31,而這並非有效的日期。讓前導零為可選的可以是另一個增強功能。

如果您想要強制分隔符一致,可以使用 反向參照^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$ 會匹配 1999-01-01,但不會匹配 1999/01-01

同樣地,您要讓正規表示式多麼複雜取決於您使用它的資料,以及如果出現不想要的匹配,問題會有多嚴重。如果您在腳本中驗證使用者的日期輸入,在正規表示式之外執行某些檢查可能比較容易。例如,當年份不是閏年時排除 2 月 29 日,在腳本語言中執行會容易得多。使用簡單的算術來檢查年份是否可被 4 整除(且不可被 100 整除,除非可被 400 整除),會比使用正規表示式容易得多。

以下是如何在 Perl 中檢查有效的日期。我也加入了括號,將年份擷取到反向參照中。

sub isvaliddate {
  my $input = shift;
  if ($input =~ m!^((?:19|20)\d\d)[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$!) {
    # At this point, $1 holds the year, $2 the month and $3 the day of the date entered
    if ($3 == 31 and ($2 == 4 or $2 == 6 or $2 == 9 or $2 == 11)) {
      return 0; # 31st of a month with 30 days
    } elsif ($3 >= 30 and $2 == 2) {
      return 0; # February 30th or 31st
    } elsif ($2 == 2 and $3 == 29 and not ($1 % 4 == 0 and ($1 % 100 != 0 or $1 % 400 == 0))) {
      return 0; # February 29th outside a leap year
    } else {
      return 1; # Valid date
    }
  } else {
    return 0; # Not a date
  }
}

若要比對 mm/dd/yyyy 格式的日期,請將正規表示法重新排列為 ^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$。對於 dd-mm-yyyy 格式,請使用 ^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$。您可以在 RegexBuddy 的程式庫 中找到這些正規表示法的其他變體。