Regular Expression Match เพื่อทดสอบปีที่ถูกต้อง


92

ด้วยค่าที่ฉันต้องการตรวจสอบเพื่อตรวจสอบว่าเป็นปีที่ถูกต้องหรือไม่ เกณฑ์ของฉันง่ายมากโดยที่ค่าควรเป็นจำนวนเต็มพร้อม4อักขระ ฉันรู้ว่านี้ไม่ได้เป็นทางออกที่ดีที่สุดเท่าที่มันจะไม่อนุญาตให้เมื่อหลายปีก่อนและจะช่วยให้ปีเช่น1000 5000เกณฑ์นี้เพียงพอสำหรับสถานการณ์ปัจจุบันของฉัน

สิ่งที่ฉันคิดขึ้นมาคือ

\d{4}$

แม้ว่าจะใช้งานได้ แต่ก็อนุญาตให้ใช้ค่าลบได้

ฉันจะแน่ใจได้อย่างไรว่าอนุญาตเฉพาะจำนวนเต็มบวกเท่านั้น


fwiw ฉันสร้างโปรเจ็กต์ node.js ไปยัง regex-rangeเพื่อสร้างช่วงเหล่านี้โดยอัตโนมัติ มันยากกว่าที่คิดหากคุณต้องสร้าง regex เพื่อทดสอบเป็นเวลาหลายปี
jonschlinkert

ทำไมต้อง จำกัด การตรวจสอบความถูกต้องของคุณไว้ที่ 4 หลักปี? longnow.org
Dan Temple

คำตอบ:


78

คุณต้องเพิ่มจุดยึดเริ่มต้น^เป็น:

^\d{4}$

regex ของคุณ\d{4}$จะตรงกับสายที่ลงท้ายด้วยเลข 4 หลัก ดังนั้นการป้อนข้อมูลเช่น-1234จะได้รับการยอมรับ

การเพิ่มจุดยึดเริ่มต้นจะทำให้คุณจับคู่เฉพาะสตริงที่ขึ้นต้นและลงท้ายด้วย 4 หลักซึ่งหมายความว่าต้องมีเพียง 4 หลักเท่านั้น


2
ประณาม! ของฉันมีข้อบกพร่องมากจนน่าจะยอมรับwhateverblahblah2323ได้ ตอนนี้ฉันเข้าใจแล้วว่าทำไมการเรียนรู้เพียงเล็กน้อยจึงอันตราย: O
Ranhiru Jude Cooray

62
สิ่งนี้จะแตกในปี 10,000
sferik

16
@sferik: ไม่สำคัญ ผู้โพสต์ต้นฉบับระบุโดยเฉพาะว่าเขาต้องการตรวจสอบอักขระสี่ตัว เขาไม่ได้ระบุว่าเขาต้องการให้ปี 10,000 เป็นข้อมูลที่ถูกต้องดังนั้นการยอมรับ10000จะเป็นจุดบกพร่อง
markusk

4
@sferik: โปรแกรมนี้จะหายไปหลายศตวรรษแล้ว ถ้าไม่เช่นนั้นควรกังวลถึง 9,000 ปีในอนาคต ตามหลักการของ YAGNI แนวทางนี้ใช้ได้
ฟิลิป

183

ปีตั้งแต่ 1,000 ถึง 2999

^[12][0-9]{3}$

สำหรับ 1900-2099

^(19|20)\d{2}$

14
นี่เป็นทางออกที่ดีกว่ามาก
mk_89

10
ฉันควรใช้กลุ่มที่ไม่จับภาพ:^(?:19|20)\d{2}$
Eldar Agalarov

ฉันจะตรวจสอบความถูกต้องของปี 4 หลักระหว่างปี 2011 และ 2099 ได้อย่างไร
mcquaim

ฉัน(19|20)\d{2}จะเพิ่มลงใน regex เพื่อตรวจสอบความถูกต้องของรูปแบบวันเกิดได้อย่างไร นี่คือ regex ของ/^[0-9]{1,2}\/(0[1-9])|(1[0-2])\/[0-9]{4}$/ฉันฉันต้องการให้แน่ใจว่าปีมีตัวเลข 4 หลักเสมอและเริ่มเหี่ยวแห้ง 19 ** หรือ 20 **
ltdev

ใช้ ^ (19 | 2 [0-9]) \ d {2} $ สำหรับปี 1900 - 2999
MarcoZen

22

คำตอบที่ "ยอมรับ" สำหรับคำถามนี้มีทั้งไม่ถูกต้องและเป็นสายตาสั้น

ไม่ถูกต้องเนื่องจากจะจับคู่สตริงเช่น0001ซึ่งไม่ใช่ปีที่ถูกต้อง

มันเป็นสายตาสั้นที่จะไม่ตรงกับค่าใด ๆ ที่สูงกว่า 9999 เราลืมบทเรียนของY2K ไปแล้วหรือยัง? ให้ใช้นิพจน์ทั่วไปแทน:

^[1-9]\d{3,}$

หากคุณต้องการจับคู่ปีในอดีตนอกเหนือจากปีในอนาคตคุณสามารถใช้นิพจน์ทั่วไปนี้เพื่อจับคู่จำนวนเต็มบวก:

^[1-9]\d*$

แม้ว่าคุณจะไม่คาดหวังวันที่ในอดีต แต่คุณอาจต้องการใช้นิพจน์ทั่วไปนี้อยู่ดีในกรณีที่มีคนประดิษฐ์ไทม์แมชชีนและต้องการนำซอฟต์แวร์ของคุณกลับไปด้วย

หมายเหตุ: นิพจน์ทั่วไปนี้จะจับคู่ปีทั้งหมดรวมถึงปีก่อนปี 1 เนื่องจากโดยทั่วไปแล้วนิพจน์เหล่านี้จะแสดงด้วยการกำหนด BC แทนที่จะเป็นจำนวนเต็มลบ แน่นอนว่าอนุสัญญานี้อาจเปลี่ยนแปลงได้ในอีกไม่กี่พันปีข้างหน้าดังนั้นตัวเลือกที่ดีที่สุดของคุณคือจับคู่จำนวนเต็มใด ๆ - บวกหรือลบ - ด้วยนิพจน์ทั่วไปต่อไปนี้:

^-?[1-9]\d*$

3
ไม่น่าจะเป็นไปได้ แต่บางคน (นักโบราณคดี? นักประวัติศาสตร์?) อาจต้องเทียบเคียงกันเมื่อ 8000 ปีก่อน : D และ Doc Brown อาจต้องการมัน ...
Jaime

1
ฉันใช้สิ่งนี้เพื่อ จำกัด ช่วงตั้งแต่ 1,000-9999 ^ [1-9] \\ d {3} $ นั่นเพราะแอปพลิเคชันที่เราต้องให้ข้อมูลยอมรับตัวเลข 4 หลักเท่านั้น :(
MatPag

คำตอบที่ยอดเยี่ยม ฉันจะทำให้ต่อไปนี้ยอมรับปี 0 ​​ด้วย: ^ (-? [1-9] \ d * | 0) $
Kosta Kontos

10

สิ่งนี้ใช้ได้กับ 1900 ถึง 2099:

/(?:(?:19|20)[0-9]{2})/

ดูเหมือนว่าฉันจะไปถึงปี 2099 เท่านั้น BTW OP กำลังถามว่าจะอนุญาตเฉพาะตัวเลข 4 หลักที่เป็นบวกได้อย่างไร
DeanOC

ใช่ปี 2099 คือสิ่งที่ฉันหมายถึง ขอบคุณ. และตอนนี้ฉันเห็นส่วนจำนวนเต็มบวก
jonschlinkert

ฉันสร้างโปรเจ็กต์เป็น regex-rangeเพื่อสร้างช่วงเหล่านี้โดยอัตโนมัติ
jonschlinkert

5

สร้างคำตอบ @ r92 สำหรับปี 1970-2019:

(19[789]\d|20[01]\d)

คำตอบของคุณอนุญาต197999
avalanche1

ฉันไม่คิดว่ามันจะ ... regex 19[789]\d\d\dจะอนุญาต197999
มองซิเออร์

1
/(19[789]\d|20[01]\d)/.test(1970324) >> true
หิมะถล่ม 1

ใช่มันจะตรงกับ 4 ตัวแรก ( 1970) ไม่ใช่ 3 ตัวสุดท้ายแล้ว(19[789]\d|20[01]\d)[^0-9]ล่ะ? นั่นจะตรงกัน1970 324แต่ไม่ใช่1970324
มองซิเออร์

1
ฉันพบว่าสิ่งนี้มีประโยชน์สำหรับการค้นหาปีภาพยนตร์จากชื่อไฟล์ ... ในกรณีนี้เราต้องการของตั้งแต่ปี 1930 เป็นต้นไป ... แต่เราจะไม่รวม 1024 ที่เพิ่มเข้ามาในตอนท้ายเพื่อคุณภาพของวิดีโอ
Adrian Hum

2

ในการทดสอบปีในสตริงที่มีคำอื่นร่วมกับปีคุณสามารถใช้ regex ต่อไปนี้: \ b \ d {4} \ b


นี่คือสิ่งที่ฉันต้องการคำตอบที่ยอมรับดูเหมือนจะไม่ใช่ PCRE ที่ถูกต้อง
Prometheus

2

ในทางทฤษฎีตัวเลือก 4 หลักถูกต้อง แต่ในทางปฏิบัติมันอาจจะดีกว่าถ้ามีช่วง 1900-2099

นอกจากนี้ต้องเป็นกลุ่มที่ไม่จับภาพ ความคิดเห็นและคำตอบจำนวนมากเสนอให้มีการจัดกลุ่มซึ่งไม่เหมาะสมกับ IMHO เนื่องจากสำหรับการจับคู่อาจใช้งานได้ แต่สำหรับการแยกการจับคู่โดยใช้ regex มันจะดึงตัวเลข 4 หลักและตัวเลขสองหลัก (19 และ 20) ออกด้วยเนื่องจาก paranthesis

สิ่งนี้จะใช้ได้กับการจับคู่แบบตรงทั้งหมดโดยใช้กลุ่มที่ไม่จับภาพ:

(?:19|20)\d{2}


1

คุณสามารถใช้ sth เช่น [ ^-]\d{4}$: คุณป้องกันไม่ให้เครื่องหมายลบ-อยู่ก่อน 4 หลักของคุณ
คุณยังสามารถใช้^\d{4}$กับ^การจับจุดเริ่มต้นของสตริง ขึ้นอยู่กับสถานการณ์ของคุณจริงๆ ...


1

ใช้;

^(19|[2-9][0-9])\d{2}$ 

สำหรับปี 1900 - 9999

ไม่ต้องกังวลสำหรับ 9999 เป็นต้นไป - AI จะทำการเขียนโปรแกรมทั้งหมดในตอนนั้น !!! ฮิฮิฮิฮิ

คุณสามารถทดสอบ regex ของคุณได้ที่https://regex101.com/

ข้อมูลเพิ่มเติมเกี่ยวกับกลุ่มที่ไม่ได้จับภาพ (ดังที่กล่าวไว้ในความคิดเห็นด้านบน) ที่นี่http://www.manifold.net/doc/radian/why_do_non-capture_groups_exist_.htm


0

คุณสามารถแปลงจำนวนเต็มของคุณเป็นสตริง เนื่องจากเครื่องหมายลบจะไม่ตรงกับตัวเลขคุณจึงไม่มีปีติดลบ


0

ฉันใช้ regex นี้ใน Java ^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|[2-9][0-9])[0-9]{2}$

ทำงานตั้งแต่ปี 1900 ถึง 9999


0

/ ^ \ d {4} $ / การดำเนินการ นี้จะตรวจสอบว่าสตริงประกอบด้วยตัวเลขเพียง 4 ตัวหรือไม่ ในสถานการณ์สมมตินี้ในการป้อนปี 989 คุณสามารถให้ 0989 แทน


0

หากคุณต้องการจับคู่ YYYY หรือ YYYYMMDD คุณสามารถใช้:

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

0

คุณยังสามารถใช้อันนี้

([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01]\d)

พวกเขาต้องการจับคู่ปีเท่านั้น ยิ่งไปกว่านั้น regex ของคุณจับคู่00/00/2000หรือ31/02/1999และวันที่ผิดพลาด
โตโต้

อาจช่วยคุณได้ ([0-2] [0-9] | 3 [0-1]) \ / ([0-1] [0-2]) \ / (19 [789] \ d | 20 [01 ] \ d)
Ranjeet Chouhan

(0[1-9]|1[0-2])เป็นการแสดงออกที่ดีขึ้นมากสำหรับเดือนนี้
EZ-C

0

ในกรณีของฉันฉันต้องการจับคู่สตริงที่ลงท้ายด้วยปี (4 หลัก) เช่นนี้:

Oct 2020
Nov 2020
Dec 2020
Jan 2021

มันจะกลับมาtrueพร้อมกับสิ่งนี้:

var sheetName = 'Jan 2021';
var yearRegex = new RegExp("\\d{4}$");
var isMonthSheet = yearRegex.test(sheetName);
Logger.log('isMonthSheet = ' + isMonthSheet);

โค้ดข้างต้นจะใช้ในสคริปต์ของแอป

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