ValiDate ISO 8601 โดย RX


16

ท้าทาย

ค้นหา regex ที่สั้นที่สุด

  1. ตรวจสอบความถูกต้องเช่นการจับคู่ทุกวันที่เป็นไปได้ในปฏิทินเกรโกเรียนProleptic (ซึ่งใช้กับวันที่ทั้งหมดก่อนที่จะนำไปใช้ครั้งแรกใน 1582) และ
  2. ไม่ตรงกับวันใด ๆ ที่ไม่ถูกต้อง

เอาท์พุต

การส่งออกจึงเป็นความจริงหรือเท็จ

อินพุต

อินพุตอยู่ในรูปแบบวันที่ISO 8601ที่ขยายเพิ่ม 3 รูปแบบ - ไม่มีเวลา

สองรายการแรกคือ±YYYY-MM-DD(ปีเดือนวัน) และ±YYYY-DDD(ปีวัน) ทั้งสองต้องการปลอกพิเศษสำหรับวันอธิกสุรทิน พวกมันถูกจับคู่อย่างไร้เดียงสาโดย RXs ที่ขยายเพิ่มเหล่านี้

(?<year>[+-]?\d{4,})-(?<month>\d\d)-(?<day>\d\d)
(?<year>[+-]?\d{4,})-(?<doy>\d{3})

รูปแบบอินพุตที่สามคือ±YYYY-wWW-D(ปี, สัปดาห์, วัน) มันเป็นสิ่งที่ซับซ้อนเพราะรูปแบบการกระโดดสัปดาห์ที่ซับซ้อน

(?<year>-?\d{4,})-W(?<week>\d\d)-(?<dow>\d)

การตรวจสอบความถูกต้องพื้นฐาน แต่ไม่เพียงพอสำหรับการรวมกันทั้งสามจะมีลักษณะดังนี้:

[+-]?\d{4,}-((0\d|1[0-2])-([0-2]\d|3[01]) ↩
            |([0-2]\d\d|3[0-5]\d|36[0-6]) ↩
            |(W([0-4]\d|5[0-3])-[1-7]))

เงื่อนไข

ปีอธิกสุรทินในปฏิทินเกรกอเรียนโกเรียนมีวันก้าวกระโดด …-02-29และทำให้มันเป็น 366 วันนานจึง…-366มีอยู่ เหตุการณ์นี้เกิดขึ้นในปีใดก็ตามที่มีเลขลำดับหารด้วย 4 แต่ไม่เท่ากับ 100 เว้นแต่จะหารด้วย 400 ปีศูนย์มีอยู่ในปฏิทินนี้และเป็นปีอธิกสุรทิน

ปีในปฏิทินสัปดาห์ ISO มีสัปดาห์ที่ 53 ซึ่งใครสามารถคำ“ เผ่นสัปดาห์ ” สิ่งนี้เกิดขึ้นในทุก ๆ ปีที่ 1 มกราคมเป็นวันพฤหัสบดีและจะเพิ่มขึ้นทุกปี ปรากฎว่าเกิดขึ้นทุก ๆ 5 หรือ 6 ปีตามปกติในรูปแบบที่ไม่ปกติ

ปีมีตัวเลขอย่างน้อย 4 หลัก ปีที่มีตัวเลขมากกว่า 10 หลักไม่จำเป็นต้องได้รับการสนับสนุนเพราะมันใกล้พอที่จะอายุของจักรวาล (ประมาณ 14 พันล้านปี) เครื่องหมายบวกชั้นนำเป็นตัวเลือกถึงแม้ว่ามาตรฐานจริงแนะนำว่าควรใช้เวลาหลายปีด้วยตัวเลขมากกว่า 4 หลัก

ต้องไม่ยอมรับวันที่บางส่วนหรือที่ถูกตัดทอนเช่นที่น้อยกว่าความแม่นยำของวัน

ส่วนของสัญกรณ์วันที่เช่นเดือนนั้นไม่จำเป็นต้องจับคู่โดยกลุ่มที่สามารถอ้างอิงได้

กฎระเบียบ

นี่คือรหัสกอล์ฟ regex ที่สั้นที่สุดโดยไม่ต้องใช้รหัสชนะ อัปเดต:คุณอาจใช้คุณสมบัติเช่นการเรียกซ้ำและกลุ่มที่มีความสมดุล แต่จะถูกปรับเป็นจำนวน 10 ซึ่งการนับตัวละครจะถูกคูณด้วย! นี่คือตอนที่แตกต่างจากกฎระเบียบในกอล์ฟรหัสฮาร์ด: Regex สำหรับหาร 7 คำตอบก่อนหน้านี้ชนะเสมอกัน

กรณีทดสอบ

การทดสอบที่ถูกต้อง

2015-08-10
2015-10-08
12015-08-10
-2015-08-10
+2015-08-10
0015-08-10
1582-10-10
2015-02-28
2016-02-29
2000-02-29
0000-02-29
-2000-02-29
-2016-02-29
200000-02-29
2016-366
2000-366
0000-366
-2016-366
-2000-366
2015-081
2015-W33-1
2015-W53-7
 2015-08-10 

ส่วนสุดท้ายเป็นทางเลือกที่ถูกต้องเช่นช่องว่างนำหน้าและต่อท้ายในสตริงอินพุตอาจถูกตัดออก

รูปแบบไม่ถูกต้อง

-0000-08-10     # that's an arbitrary decision
15-08-10        # year is at least 4 digits long
2015-8-10       # month (and day) is exactly two digits long, i.e. leading zero is required
015-08-10       # year is at least 4 digits long
20150810        # though a valid ISO format, we require separators; could also be interpreted as a 8-digit year
2015 08 10      # separator must be hyphen-minus
2015.08.10      # separator must be hyphen-minus
2015–08–10      # separator must be hyphen-minus
2015-0810
201508-10       # could be October in the year 201508
2015 - 08 - 10  # no internal spaces allowed
2015-w33-1      # letter ‘W’ must be uppercase
2015W33-1       # it would be unambiguous to omit the separator in front of a letter, but not in the standard
2015W331        # though a valid ISO format we require separators
2015-W331
2015-W33        # a valid ISO date, but we require day-precision
2015W33

วันที่ไม่ถูกต้อง

2015        # a valid ISO format, but we require day-precision
2015-08     # a valid ISO format, but we require day-precision
2015-00-10  # month range is 1–12
2015-13-10  # month range is 1–12
2015-08-00  # day range is 1–28 through 31
2015-08-32  # max. day range is 1–31
2015-04-31  # day range for April is 1–30
2015-02-30  # day range for February is 1–28 or 29
2015-02-29  # day range for common February is 1–28
2100-02-29  # most century years are non-leap
-2100-02-29 # most century years are non-leap
2015-000    # day range is 1–365 or 366
2015-366    # day range is 1–365 in common years
2016-367    # day range is 1–366 in leap years
2100-366    # most century years are non-leap
-2100-366   # most century years are non-leap
2015-W00-1  # week range is 1–52 or 53
2015-W54-1  # week range is 1–53 in long years
2016-W53-1  # week range is 1–52 in short years
2015-W33-0  # day range is 1–7
2015-W33-8  # day range is 1–7

2
คำถามนี้ยังไม่ชัดเจนเนื่องจากไม่มีการระบุภาษา regex
orlp

1
@orlp หากไม่ได้ระบุตัวเลือกจะไม่ จำกัด ฉันเขียน“ regex” หรือ“ RX” โดยมีจุดประสงค์ดังนั้นจึงสามารถใช้ภาษาถิ่นที่อนุญาตการเรียกซ้ำ ฯลฯ (เช่น CFG ไม่ใช่ RG)
Crissov

ฉันขอแนะนำให้คุณ จำกัด ภาษา regex เพราะจะมีรสเปรี้ยวมากสำหรับผู้แข่งขันที่จะทำงานเป็นเวลาหลายชั่วโมงในการแก้ปัญหาเท่านั้นที่จะพ่ายแพ้เล็กน้อยโดยภาษาที่มีประสิทธิภาพมากขึ้นโดยพื้นฐาน หากคุณต้อง จำกัด ภาษาให้เป็นไปตามข้อกำหนด CS จริงของนิพจน์ทั่วไป (เช่น DFA) ปัญหาจะกลายเป็นคำตอบการเพิ่มประสิทธิภาพที่น่าสนใจ
orlp

การตรวจสอบความถูกต้องของวันที่ ISO-8601 โดยใช้นิพจน์ทั่วไปเป็นสิ่งที่ฉันต้องทำจริง ๆ เพื่อทำงาน แต่เห็นด้วยกับ orlp ฉันคิดว่าภาษาเป็นสิ่งจำเป็นที่นี่
Alex A.

1
Regex สืบทอดมาจาก Method ใน Perl 6 ดังนั้นมันจึงเป็นรูปแบบของโค้ดที่สามารถเรียกทำงานได้
แบรดกิลเบิร์ต b2gills

คำตอบ:


4

PCRE (เช่น Perl), 778 ไบต์

/^([+-]?\d*((([02468][048]|[13579][26]|\d\d(?!00))([02468][048]|[13579][26]))|\d{4}(?!-02-29|-366))-((?!02-3|(0[469]|11)-31|000)((0[1-9]|1[012])-(0[1-9]|[12]\d|30|31)|([012]\d\d|3([0-5]\d|6[0-6])))|(W(?!00)([0-4]\d|51|52)-[1-7]))|((\+?\d*([02468][048]|[13579][26])|-\d*([02468][159]|[13579][37]))(04|09|15|20|26|32|37|43|48|54|60|65|71|76|82|88|93|99)|(\+?\d*([02468][159]|[13579][37])|-\d*([02468][26]|[13579][048]))(05|11|16|22|28|33|39|44|50|56|61|67|72|78|84|89|95)|(\+?\d*([02468][26]|[13579][048])|-\d*([02468][37]|[13579][159]))(01|07|12|18|24|29|35|40|46|52|57|63|68|74|80|85|91|96)|\+?\d*(([02468][37]|[13579][159])(03|14|20|25|31|36|42|53|59|64|70|76|81|87|92|[049]8))|-\d*(([02468][048]|[13579][26])([059]2|08|13|19|24|30|36|41|47|58|64|69|75|80|86|97)))-W53-[1-7])$/

ฉันได้รวมตัวคั่นในจำนวนไบต์เพื่อแสดงว่าไม่ต้องพึ่งพาแฟล็กใด ๆ

มันไม่ได้ตรงกับวันที่ที่ถูกต้องภายในสายอื่น ๆ 1234-56-89 2016-02-29 9876-54-32เช่น regex สั้นลงโดยไม่ตรวจสอบตัวเลขสูงสุด 10 หลักสำหรับปี

ขยายด้วยความคิดเห็น:

/^  # Start of pattern (no leading space)
  (
    # YEAR
    # Optional sign and digits if more than 4 in year
    [+-]?\d*(
      # Years 00??, 04??, 08?? ... 92??, 96?? OR dd not followed by 00
      # followed by 00, 04, 08 ... 92, 96 OR
      (([02468][048]|[13579][26]|\d\d(?!00))([02468][048]|[13579][26])) |
      # any year not followed by 29 February or day 366
      \d{4}(?!-02-29|-366)
    # dash
    ) -
    # MONTH AND DAY, or DAY OF YEAR, or WEEK OF YEAR AND DAY if less than 53 weeks
    (
      # Not (30 or 31 February OR 31 April, June, September or December OR day 0)
      (?!02-3|(0[469]|11)-31|000)
      (
        # Month         dash         day         OR
        (0[1-9]|1[012]) - (0[1-9]|[12]\d|30|31) |
        # 001-299 OR 300-359 OR 360-366
        ([012]\d\d | 3([0-5]\d | 6[0-6]))
      # OR
      ) |
      (
        # W    01-52    dash    1-7
        W(?!00)([0-4]\d|51|52)-[1-7]
      )
    # OR
    ) |
    # WEEK OF YEAR AND DAY only if week is 53
    (
      # Optional plus and extra year digits
      \+?\d*(
        # Years +0303 - +9998
        ([02468][37]|[13579][159])(03|14|20|25|31|36|42|53|59|64|70|76|81|87|92|[049]8)
      ) |
      # Minus and extra year digits
      -\d*(
        # Years -0002 - -9697
        ([02468][048]|[13579][26])([059]2|08|13|19|24|30|36|41|47|58|64|69|75|80|86|97)
      ) |
      # Years +0004 - +9699, -0104 - -9799
      (\+?\d*([02468][048]|[13579][26])|-\d*([02468][159]|[13579][37]))
          (04|09|15|20|26|32|37|43|48|54|60|65|71|76|82|88|93|99) |
      # Years +0105 - +9795, -0205 - -9895
      (\+?\d*([02468][159]|[13579][37])|-\d*([02468][26]|[13579][048]))
          (05|11|16|22|28|33|39|44|50|56|61|67|72|78|84|89|95) |
      # Years +0201 - +9896, -0301 - -9996
      (\+?\d*([02468][26]|[13579][048])|-\d*([02468][37]|[13579][159]))
          (01|07|12|18|24|29|35|40|46|52|57|63|68|74|80|85|91|96)
    # dash W 53 dash 1-7
    )-W53-[1-7]
  # End of pattern (no trailing space)
  )$/x

ฉันยังไม่ได้ตรวจสอบทุกอย่าง แต่ดูเหมือนว่าคุณจะได้รับจำนวนไบต์มากที่สุด(?!…)เมื่อเทียบกับโซลูชันของฉัน
Crissov

1
@Crissov (?!…)นิพจน์บันทึกเฉพาะสองสามไบต์ต่อครั้ง ฉันลดจำนวนไบต์ลงมากด้วยการรวมรูปแบบสัปดาห์บวก / ลบสามสัปดาห์ / ปี / วันของสัปดาห์เป็นหนึ่งฉบับ คนสุดท้ายไม่ตรงกับคนอื่น ดังนั้นฉันจึงมี 8 รูปแบบย่อยยาวลงไปที่ 5 นอกจากนี้เนื่องจาก|20|25|ความยาวเดียวกันกับที่|2[05]|ฉันไปสำหรับตัวเลือกที่อ่านได้มากขึ้น
CJ Dennis

นิพจน์นี้ตรงกับกรณีทดสอบ -0000-08-10และไม่ตรง␠2015-08-10␠กับช่องว่างนำหน้าและต่อท้าย แต่เนื่องจากทั้งคู่เป็นการตัดสินใจตามอำเภอใจหรือคุณลักษณะที่เป็นตัวเลือกฉันจะให้มันเลื่อน
Crissov

ฉันคิดว่าวิธีนี้มีข้อบกพร่องสำหรับวันที่ภายใน W50
Crissov

W(?!00)([0-4]\d|51|52)-[1-7]W(?!00)([0-4]\d|5[0-2])-[1-7]ต้องเป็นสิ่งที่เทียบเท่ากับ สิ่งนี้จะเพิ่มอักขระหนึ่งตัวตามความยาว 779
Crissov

9

PCRE: 603 940 947 949 956 ไบต์

^\s*[+-]?(\d{4,10}-((00[1-9]|0[1-9]\d|[12]\d\d|3[0-5]\d|36[0-5])|(0[1-9]|1[0-2])-(0[1-9]|1\d|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31|W(0[1-9]|[1-4]\d|5[0-2])-[1-7]))|((\d{2,8}([13579][26]|[2468][048]|0[48])|(\d{0,6}([13579][26]|[02468][048])00))-(366|02-29))|(\+?\d{0,6}(([02468][048]|[13579][26])([26]0|71|[38]2|[49]3|[05]4|15|[27]6|37|[48]8|[09]9)|([02468][159]|[13579][37])(50|[16]1|[27]2|33|[48]4|[09]5|[15]6|67|[27]8|[38]9)|([02468][26]|[13579][048])([48]0|[09]1|[15]2|63|[27]4|[38]5|[49]6|[05]7|[16]8|29)|([02468][37]|[13579][159])([27]0|[38]1|[49]2|[05]3|[16]4|25|[37]6|87|[049]8|[5]9))|-\d{0,6}(([02468][048]|[13579][26])(0[28]|1[39]|24|3[06]|4[17]|5[28]|6[49]|75|8[06]|9[27])|([02468][159]|[13579][37])(0[49]|15|2[06]|3[27]|4[38]|54|6[05]|7[16]|8[28]|9[39])|([02468][26]|[13579][048])(0[51]|16|2[28]|3[39]|44|5[06]|6[17]|7[28]|8[49]|95)|([02468][37]|[13579][159])(0[17]|1[28]|2[49]|35|4[06]|5[27]|6[38]|74|8[05]|9[16])))-W53-[1-7]\s*$

หมายเหตุ:อาจมีวงเล็บบางคู่

การหารด้วย 4

ผลคูณของ 4 ซ้ำในรูปแบบง่าย ๆ :

  • 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, ...

สิ่งนี้หรือสิ่งที่ตรงกันข้ามสามารถจับคู่โดยการแสดงออกปกติอย่างง่ายเช่นเดียวกันสำหรับตัวเลขสองหลักทั้งหมดที่มีศูนย์นำ:

(?<divisible-by-four>[13579][26]|[02468][048])
(?<not-divisible-by-four>[13579][048]|[02468][26]|\d[13579])

มันสามารถบันทึกบางไบต์หากมีคลาสตัวอักษรสำหรับเลขคี่และเลขคู่ (เช่น\oและ\e) แต่ก็ไม่เท่าที่ฉันทราบ

ปี

นิพจน์นั้นจะพอเพียงสำหรับปฏิทินจูเลียน แต่การตรวจสอบปีอธิกสุรทินเกรโกเรียนจำเป็นต้องมีการติดตามกรณีพิเศษ00ด้วยการแบ่งแยกศตวรรษโดย 4:

(?<leap-year>[+-]?(\d{2,8}([13579][26]|[2468][048]|0[48])|(\d{0,6}([13579][26]|[02468][048])00))
(?<year>[+-]?\d{4,10})

สิ่งนี้จะต้องมีการเปลี่ยนแปลงนอกกฎหมาย-0000-…(รวมถึง-00000-…อื่น ๆ ) หรือบังคับใช้เครื่องหมายบวกสำหรับตัวเลขปีบวกที่มีตัวเลขมากกว่า 4 หลัก หลังจะค่อนข้างง่าย แต่ไม่จำเป็น:

(?<leap-year>([+-]?(\d\d([13579][26]|[2468][048]|0[48])|(([13579][26]|[02468][048])00)))|([+-](\d{3,8}([13579][26]|[2468][048]|0[48])|(\d{1,6}([13579][26]|[02468][048])00))))
(?<year>([+-]?\d{4})|([+-]\d{5,10}))

วันของปี

วันที่สามหลักค่อนข้างง่ายเราแค่ จำกัด-366การกระโดดปี (และไม่อนุญาต-000)

(?<ordinal-day>-(00[1-9]|0[1-9]\d|[12]\d\d|3[0-5]\d|36[0-5]))
(?<ordinal-leap-day>-366)

วันเดือนปี

เจ็ดเดือนกับ 31 วันคือ01มกราคม, 03มีนาคม, 05พฤษภาคม, 07กรกฎาคม, 08สิงหาคม, 10ตุลาคมและ12ธันวาคม แค่สี่เดือนก็มี 30 วัน04เมษายน06มิถุนายน09กันยายนและ11พฤศจิกายน ในที่สุด02กุมภาพันธ์มี 28 วันในปีสามัญและ 29 ในปีอธิกสุรทิน ครั้งแรกที่เราสามารถสร้างการแสดงออกปกติสำหรับวันที่ถูกต้องเสมอ01ผ่าน28แล้วเพิ่มกรณีพิเศษ

(?<month-day>-(0[1-9]|1[0-2])-(0[1-9]|1\d|2[0-8]))
(?<short-month-day>-(0[13-9]|1[0-2])-(29|30))
(?<long-month-day>-(0[13578]|1[02])-31)
(?<month-leap-day>-02-29)

ทั้งเดือนหรือวันจะต้อง00ไม่ได้รับการคุ้มครองโดยรุ่นก่อนหน้า

วันในสัปดาห์ของปี

ทุกปีรวมถึง 52 สัปดาห์

(?<week-day>-W(0[1-9]|[1-4]\d|5[0-2])-[1-7])

ปียาวที่มีการวน-W53ซ้ำในรอบ 400 ปีเช่นเพิ่ม 2000 สำหรับวัฏจักรปัจจุบันและค้นหาปีปัจจุบันในรายการที่สาม:

  • 004, 009, 015, 020, 026, 032, 037, 043, 048, 0560, 060, 065, 071, 076, 082, 088, 093, 099,
  • 105, 111, 116, 122, 128, 133, 139, 144, 150, 156, 161, 167, 172, 178, 184, 189, 195,
  • 201, 207, 212, 218, 224, 229, 235, 240, 246, 252, 257, 263, 268, 274, 280, 285, 291, 296,
  • 303, 308, 314, 320, 325, 331, 336, 342, 348, 353, 359, 364, 370, 376, 381, 387, 392, 398

แต่ละสี่ศตวรรษมีรูปแบบที่ไม่ซ้ำกัน อาจมีพื้นที่ไม่เพียงพอสำหรับการเพิ่มประสิทธิภาพ

  1. 04|09|15|20|26|32|37|43|48|54|60|65|71|76|82|88|93|99
  2. 05|11|16|22|28|33|39|44|50|56|61|67|72|78|84|89|95
  3. 01|07|12|18|24|29|35|40|46|52|57|63|68|74|80|85|91|96
  4. 03|08|14|20|25|31|36|42|48|53|59|64|70|76|81|87|92|98

เราสามารถจัดกลุ่มตามหลักเพื่อค้นหาว่าเราสามารถบันทึกสองไบต์หรือดังนั้น:

  • จัดกลุ่มตามหลักที่ 1
    1. 0[49]|15|2[06]|3[27]|4[38]|54|6[05]|7[16]|8[28]|9[39]
    2. 05|1[16]|2[28]|3[39]|44|5[06]|6[17]|7[28]|8[49]|95
    3. 0[17]|1[28]|2[49]|35|4[06]|5[27]|6[38]|74|8[05]|9[16]
    4. 0[38]|14|2[05]|3[16]|4[28]|5[39]|64|7[06]|8[17]|9[28]
  • จัดกลุ่มตามหลักที่ 2
    1. [26]0|71|[38]2|[49]3|[05]4|15|[27]6|37|[48]8|[09]9
    2. 50|[16]1|[27]2|33|[48]4|[09]5|[15]6|67|[27]8|[38]9
    3. [48]0|[09]1|[15]2|63|[27]4|[38]5|[49]6|[05]7|[16]8|29
    4. [27]0|[38]1|[49]2|[05]3|[16]4|25|[37]6|87|[049]8|[5]9

จำนวนศตวรรษจะถูกจับคู่ได้อย่างง่ายดายอีกครั้งโดยการเปลี่ยนแปลงของการแสดงออกหาร

  • ศตวรรษที่ 1: [02468][048]|[13579][26]
  • ศตวรรษที่ 2: [02468][159]|[13579][37]
  • ศตวรรษที่ 3: [02468][26]|[13579][048]
  • ศตวรรษที่ 4: [02468][37]|[13579][159]

จนถึงตอนนี้ใช้งานได้เฉพาะปีบวกรวมทั้งปีศูนย์ สำหรับปีเชิงลบเราต้องลบค่าจากรายการด้านบนจาก 400 และทำส่วนที่เหลืออีกครั้งเพราะรูปแบบไม่สมมาตร

  1. 02|08|13|19|24|30|36|41|47|52|58|64|69|75|80|86|92|97
  2. 04|09|15|20|26|32|37|43|48|54|60|65|71|76|82|88|93|99
  3. 05|11|16|22|28|33|39|44|50|56|61|67|72|78|84|89|95
  4. 01|07|12|18|24|29|35|40|46|52|57|63|68|74|80|85|91|96

หรือ

  1. 0[28]|1[39]|24|3[06]|4[17]|5[28]|6[49]|75|8[06]|9[27]
  2. 0[49]|15|2[06]|3[27]|4[38]|54|6[05]|7[16]|8[28]|9[39]
  3. 0[51]|16|2[28]|3[39]|44|5[06]|6[17]|7[28]|8[49]|95
  4. 0[17]|1[28]|2[49]|35|4[06]|5[27]|6[38]|74|8[05]|9[16]

วางมันทั้งหมดเข้าด้วยกัน

ปีใดก็ได้

[+-]?\d{4,10}-((00[1-9]|0[1-9]\d|[12]\d\d|3[0-5]\d|36[0-5])|(0[1-9]|1[0-2])-(0[1-9]|1\d|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31|W(0[1-9]|[1-4]\d|5[0-2])-[1-7])

วันส่งท้ายปีเก่า

[+-]?(\d{2,8}([13579][26]|[2468][048]|0[48])|(\d{0,6}([13579][26]|[02468][048])00))-(366|02-29)

การเพิ่มในรอบปี

+?\d{0,6}(([02468][048]|[13579][26])([26]0|71|[38]2|[49]3|[05]4|15|[27]6|37|[48]8|[09]9)|([02468][159]|[13579][37])(50|[16]1|[27]2|33|[48]4|[09]5|[15]6|67|[27]8|[38]9)|([02468][26]|[13579][048])([48]0|[09]1|[15]2|63|[27]4|[38]5|[49]6|[05]7|[16]8|29)|([02468][37]|[13579][159])([27]0|[38]1|[49]2|[05]3|[16]4|25|[37]6|87|[049]8|[5]9))-W53-[1-7]
-\d{0,6}(([02468][048]|[13579][26])(0[28]|1[39]|24|3[06]|4[17]|5[28]|6[49]|75|8[06]|9[27])|([02468][159]|[13579][37])(0[49]|15|2[06]|3[27]|4[38]|54|6[05]|7[16]|8[28]|9[39])|([02468][26]|[13579][048])(0[51]|16|2[28]|3[39]|44|5[06]|6[17]|7[28]|8[49]|95)|([02468][37]|[13579][159])(0[17]|1[28]|2[49]|35|4[06]|5[27]|6[38]|74|8[05]|9[16]))-W53-[1-7]

รูปแบบของคุณไม่ได้ถูกยึดที่จุดเริ่มต้นและจุดสิ้นสุดดังนั้นมันจะจับคู่วันที่ที่ถูกต้องภายในสตริงที่ไม่ถูกต้อง
CJ Dennis

@CDDennis นั่นเป็นเรื่องจริงฉันจะเพิ่มตัวละครทั้งสองตอนนี้
Crissov

\s*ฉันยังได้เพิ่มชั้นนำที่เป็นตัวเลือกและช่องว่างต่อท้าย
Crissov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.