日付形式dd / mm / yyyyを検証する正規表現


172

dd/mm/yyyy正規表現でフォーマットの日付文字列を検証する必要があります。

この正規表現は検証しますがdd/mm/yyyy、次のような無効な日付は検証しません31/02/4500

^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$

dd/mm/yyyyうるう年をサポートする形式を検証するための有効な正規表現とは何ですか?


3
この正規表現は実際にはうるう年を正しく検証しないため、正確な期待値を設定すると役立つと思います。たとえば、2013年2月29日はありませんが、この正規表現は、そのようなものが有効であることを表明してい
TML

7
なぜ正規表現を使用するのですか?より簡単な(そしてより正確な)方法があります...
Dan Puzey 2013年

2
正規表現は、数値をチェックするのではなく、パターンを照合するためのものです。正規表現で可能性の高い文字列を見つけ、ホスト言語が何であれ(PHPなど)、その数値を確認します。
アンディレスター

3
この回答は、「一般的な検証タスク」のスタックオーバーフローの正規表現に関するFAQに追加されました。
aliteralmind 2014

4
@BurhanKhalid:あなたは間違っている。HTML5入力にはpattern正規表現を取るという名前の属性があり、ブラウザーはJavaScriptをまったく使用せずに正規表現に対して自動的に検証するため、正規表現は検証に最適なツールです。パターン属性に正規表現を設定するだけです!
畏敬の念

回答:


329

貼り付けた正規表現はうるう年を正しく検証していませんが、同じ投稿で検証するものがあります。私はそれをdd/mm/yyyydd-mm-yyyyまたはに変更しましたdd.mm.yyyy

^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

私はそれをアルンが彼の回答で提供したリンクとここでも少しテストしました、そしてそれはうまくいくようです。

2019年2月14日を編集:次のような日付を許可する正規表現に含まれていたカンマを削除しました 29-0,-11


9
壮大な正規表現!これは、フォーマットに従ってどれほど簡単に交換できますか?たとえば、yyyy-mm-ddおよびmm-dd-yyyyです。それを念頭に置いてそれを理解することに一生懸命に取り組みましたが、それは私の正規表現スキルを超えています。
mrswadge 2014年

7
以外にもDD/MM/YYYY、この正規表現DD/MM/YYは、それがポスターの当初の意図であったかどうか確信が持てないものも受け入れます。「YY」をサポートしない場合は、オプションの?数量詞をすべて削除してください。
user1485864 14年

2
@PurveshDesaiはそれぞれ0?0に置き換え、最後に出現したも削除し?ます。
Ofir Luzon

4
@MaraisRossouw、正解です。4桁の年には、実際には3つ?削除する必要が(?:1[6-9]|[2-9]\d)?あり(?:1[6-9]|[2-9]\d)ます。すべてをに置き換えてください。
Ofir Luzon

2
ただこれを言うために立ち寄るWOW 、そしてもちろんありがとう
Jero Dungog

266

@Ofir Luzonで指定された正規表現を、要件に応じてdd-mmm-YYYY、dd / mmm / YYYY、dd.mmm.YYYYの形式に拡張しました。同じ要件を持つ他の誰でもこれを参照できます

^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

ここでいくつかのテストケースについてテストしましたhttp://regexr.com/39tr1

この正規表現の理解を深めるには、次の画像を参照してください。 ここに画像の説明を入力してください


1
はい、どのように生成しましたか?:)
Razor

いくつかのWebサイトを使用してオンラインで生成しましたが、この画像の生成元のWebサイトも覚えていません。覚えたら参照を追加します:)
Alok Chaudhary

4
@ user3733831 8888は可能な年です。私はその年齢まで生きることを期待しています。
Dan Nissenbaum

1
うるう年にも最適です。スペイン語の短い月名のサポートも追加しました。
Fer R

2
@AlokChaudhary、ダイアグラムはdebuggex.com
Taha BASRI

69

通知:

あなたの正規表現は、「4と100の倍数で、400の倍数ではない」という年の間は機能しません。そのテストに合格した年はうるう年ではありません。例:1900、2100、2200、2300、2500など。つまり、\ d \ d00という形式のすべての年が、うるう年の同じクラスに入れられますが、これは正しくありません。– MuchToLearn

そのため、[1901-2099]でのみ正常に機能します(Whew)😊

dd / MM / yyyy:

うるう年かどうかを確認します。1900から9999までの年が有効です。dd / MM / yyyyのみ

(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)

7
この回答、dd / MM / yyyyでのみ機能します。したがって、正解です。
ロドリゴ

2
@SylvainB私はそれを修正しました
gdZeus '

2
@gdZeus 2年後も配信していただきありがとうございます。しかし、不完全なソリューションがこの辺りで長い間検証されていると考えるのは怖いです。
SylvainB、2015年

より速くするために、グループをグループ化しないようにすることができます。regexr.com/3esom ^(?:(?:(?:( ?: 0 [1-9] | 1 [0-9] | 2 [0-8])[\ /](?: 0 [1- 9] | 1 [012]))|(?:( ?: 29 | 30 | 31)[\ /](?: 0 [13578] | 1 [02]))|(?:( ?: 29 | 30 )[\ /](?: 0 [4,6,9] | 11)))[\ /](?: 19 | [2-9] [0-9])\ d \ d)|(?: 29 [\ /] 02 [\ /](?: 19 | [2-9] [0-9])(?: 00 | 04 | 08 | 12 | 16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | 96))$
Matt Vukomanovic

私はエラーを見つけたと思います:29/02/2100存在しません(2100はうるう年ではありません)が、指定されたパターンでまだ受け入れられます。
KnorxThieus 2017


12

以下は、ユーザーのロケールがユリウス暦からグレゴリオ暦に切り替わった時期を知らなくても、期待どおりに正確であると思います。

順序に関係なく、年、月、日の区切り文字として「-」、「/」、または何も受け付けません。

MMddyyyy:

^(((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))[-/]?[0-9]{4}|02[-/]?29[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$

ddMMyyyy:

^(((0[1-9]|[12][0-9]|30)[-/]?(0[13-9]|1[012])|31[-/]?(0[13578]|1[02])|(0[1-9]|1[0-9]|2[0-8])[-/]?02)[-/]?[0-9]{4}|29[-/]?02[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$

yyyyMMdd:

^([0-9]{4}[-/]?((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))|([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00)[-/]?02[-/]?29)$

順序以外では、これらはすべて、グレゴリオ暦がユリウス暦から分岐する1700年まで、ユリウス暦(4年ごとのうるう年)に対して正確です。これには2つの問題があります。

  1. それは、すべてではありませんが多くの規格には存在しない0000年を受け入れます。ISO 8601は0000年(1 BCEに相当)を受け入れます。
  2. グレゴリオ暦が使用されたときに失われた10〜13日をスキップしません。ただし、これは地域によって異なります。たとえば、ローマカトリック教会は1582年10月5日から10月14日までの10日間をスキップしましたが、ギリシャ(最後に切り替えた)は1923年2月16日から28日までを13日スキップし、うるう年1700年を考慮に入れる必要がありました。 1800、1900。

これは、0001年から9999年までのJavaのカレンダー実装に対してテストされており、矛盾点は、1582年の上記の10日間だけです。


YYYYMMDDの正規表現が[01 | 02 | 03 | 05 | 06 | 07 | 09 | 10 | 11 | 13 | 14 | 15] 00-02-29と誤って一致しています。修正された正規表現:^([0-9]{4}[-/]?((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))|([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048])00)[-/]?02[-/]?29)$。Pythonでテスト:repl.it/repls/DependentBestChapters
kpr

10

これらを見て完全に混乱する人のために、ここに私のスクリプトからの抜粋を示します。残念ながら、これは日付と時刻の入力で有効な数値と一致するだけであり、2月31日は有効とマークされますが、多くの人が言っているように、正規表現はこのテストを行うための最良のツールではありません。

「yyyy-MM-dd hh:mm」の形式で日付を照合するには(または、実際に任意の順序で)

var dateerrors = false;
var yearReg = '(201[4-9]|202[0-9])';            ///< Allows a number between 2014 and 2029
var monthReg = '(0[1-9]|1[0-2])';               ///< Allows a number between 00 and 12
var dayReg = '(0[1-9]|1[0-9]|2[0-9]|3[0-1])';   ///< Allows a number between 00 and 31
var hourReg = '([0-1][0-9]|2[0-3])';            ///< Allows a number between 00 and 24
var minReg = '([0-5][0-9])';                    ///< Allows a number between 00 and 59
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
$('input').filter(function () {return this.id.match(/myhtml_element_with_id_\d+_datetime/);}).each(function (e) {
    if (e > 0) {
        // Don't test the first input. This will use the default
        var val = $(this).val();
        if (val && !val.trim().match(reg)) {
            dateerrors = true;
            return false;
        }
    }
});
if (dateerrors) {
    alert('You must enter a validate date in the format "yyyy-mm-dd HH:MM", e.g. 2019-12-31 19:30');
    return false;
}

上記のスクリプトは、正規表現オブジェクトを作成することから始まります。次に、IDが特定のパターンに一致するすべての入力を検索し、それらをループします。私が見つけた最初の入力(if (e > 0))はテストしていません。

少し説明:

var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');

^マッチの開始を意味し、マッチの$終了を意味します。

return this.id.match(/myhtml_element_with_id_\d+_datetime/);

\d+は、単一または連続した整数のシーケンスに一致することを意味します。したがってmyhtml_element_with_id_56_datetimemyhtml_element_with_id_2_datetime一致しますが、一致しmyhtml_element_with_id_5a_datetimeません。


8

以下の正規表現の別のバージョンは、次の日付形式のいずれかに一致し、先行ゼロを省略できるようにします。

正規表現: ^[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}$

一致:

1/1/11 or 1.1.11 or 1-1-11 : true 01/01/11 or 01.01.11 or 01-01-11 : true 01/01/2011 or 01.01.2011 or 01-01-2011 : true 01/1/2011 or 01.1.2011 or 01-1-2011 : true 1/11/2011 or 1.11.2011 or 1-11-2011 : true 1/11/11 or 1.11.11 or 1-11-11 : true 11/1/11 or 11.1.11 or 11-1-11 : true

正規表現の可視化

Debuggexデモ


4
あなたが持っている場合は機能しません13/13/2000= Matches is true
Andrei Krasutski

3
39/39/39は日付ではありません。この回答への投票を中止してください。
ウォーレンサージェント2017年

6

ここでdd/mm/yyyy、セパレーターが-.,/年の範囲の1つになる可能性のあるものを書きました0000-9999

うるう年を扱い、先読み、キャプチャグループ、後方参照をサポートする正規表現フレーバー用に設計されています。などには無効ですd/m/yyyy。必要に応じて、さらにセパレータを追加します[-.,/]

^(?=\d{2}([-.,\/])\d{2}\1\d{4}$)(?:0[1-9]|1\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\d{4}$

regex101でテストします。Java文字列として:

"^(?=\\d{2}([-.,\\/])\\d{2}\\1\\d{4}$)(?:0[1-9]|1\\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\\d{4}$"

説明:

(?x) # modifier x: free spacing mode (for comments)
     # verify date dd/mm/yyyy; possible separators: -.,/
     # valid year range: 0000-9999

^    # start anchor

# precheck xx-xx-xxxx,... add new separators here
(?=\d{2}([-.,\/])\d{2}\1\d{4}$)

(?:  # day-check: non caturing group

  # days 01-28
  0[1-9]|1\d|[2][0-8]| 

  # february 29d check for leap year: all 4y / 00 years: only each 400
  # 0400,0800,1200,1600,2000,...
  29
  (?!.02. # not if feb: if not ...
    (?!
      # 00 years: exclude !0 %400 years
      (?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)

      # 00,04,08,12,... 
      \d{2}(?:[02468][048]|[13579][26])
    )
  )|

  # d30 negative lookahead: february cannot have 30 days
  30(?!.02)|

  # d31 positive lookahead: month up to 31 days
  31(?=.(?:0[13578]|10|12))

) # eof day-check

# month 01-12
.(?:0[1-9]|1[012])

# year 0000-9999
.\d{4}

$ # end anchor

SO Regex FAQも参照してください。失敗した場合はお知らせください。


5

このreg exをここで見つけまし

^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$

これにより、形式mm/dd/yyyyと有効な日付が正しく検証されます(は検証されませんm/d/yyyy)。

いくつかのテスト


1
2014年より前にのみ機能し、| 20(0 [0-9] | 1 [0-4])))を| 20(0 [0-9] | 1 [0-9])))に変更して、 2019
トニー・ドン

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

間の任意の日付を検証します 1900-2099


5

次の式は素晴らしく、操作が簡単です。

((((0[13578]|1[02])(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)((\/|-|.)(0[1-9]|1[0-9]|2[0-8]))))(\/|-|.)(19([6-9][0-9])|20(0[0-9]|1[0-4])))|((02)(\/|-|.)(29)(\/|-|.)(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26])))

MM / dd / YYYY形式で検証され、1960年から2016年までのうるう年のサポートが可能になります。うるう年のサポートが必要な場合は、式のこの部分を操作するだけで済みます。

(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]))

これがお役に立てば幸いです


3

月(mm)と年(yyyy)に応じて日(dd)を検証し(うるう年の2月29日も検証)、0001から9999(グレゴリオによれば無効な年は0000)の範囲の年を許可する別の回答カレンダー)

^(?:(?:(?:0[1-9]|[12]\d|3[01])/(?:0[13578]|1[02])|(?:0[1-9]|[12]\d|30)/(?:0[469]|11)|(?:0[1-9]|1\d|2[0-8])/02)/(?!0000)\d{4}|(?:(?:0[1-9]|[12]\d)/02/(?:(?!0000)(?:[02468][048]|[13579][26])00|(?!..00)\d{2}(?:[02468][048]|[13579][26]))))$

1
18/05/0017を検証しない

1

MM / DD / YYYY形式のみを受け入れるAPIを使用しています。Ofirの回答と同様に、うるう年を含む他の投稿を見つけることができなかったので、それを微調整し、必要な人のためにここに再投稿しています。

/^(?:(?:(?:0[13578]|1[02])(\/)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/

0
((((0[13578]|1[02])\/(0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)\/(0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)(\/(0[1-9]|1[0-9]|2[0-8]))))\/(19([6-9][0-9])|20([0-9][0-9])))|((02)\/(29)\/(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))

toでMM/DD/YYYYフォーマットを検証します19602028

うるう年のサポートを延長する必要がある場合は、

19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048]|3[26]|4[048])))

これも仕事です

^((((0[13578]|1[02])[/](0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)[/](0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)([/](0[1-9]|1[0-9]|2[0-8]))))[/](19([6-9][0-9])|20([0-9][0-9])))|((02)[/](29)[/](19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))

mm-dd-yyyy置き換える[/]より[-] もフォーマットを変更できる場合は、オンラインhttp://regexr.com/も確認してください


0

MM / DD / YYYYの日付には、

^((((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}$

適切な日と蛾を確認します。

正規表現を確認できることを覚えておいてください

regex101

私はこれをお勧めします:)

楽しんで!


0
^(((([13578]|0[13578]|1[02])[-](0[1-9]|[1-9]|1[0-9]|2[0-9]|3[01]))|(([469]|0[469]|11)[-]([1-9]|1[0-9]|2[0-9]|3[0]))|((2|02)([-](0[1-9]|1[0-9]|2[0-8]))))[-](19([6-9][0-9])|20([0-9][0-9])))|((02)[-](29)[-](19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))

この正規表現は、次の形式で日付を検証します。

12-30-2016(mm-dd-yyyy)または12-3-2016(mm-d-yyyy)または1-3-2016(md-yyyy)または1-30-2016(m-dd-yyyy)


0

私はそれが質問に対する正接の回答であることを知っていますが、質問の意図が「日付を検証するにはどうすればよいですか?」できる)?

例:php

$this_date_object = date_create($this_date);

if ($this_date_object == false )
    {

        // process the error

    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.