ฉันพยายามใช้รูปแบบช่วง[01-12]ใน regex เพื่อจับคู่ mm สองหลัก แต่ไม่ได้ผลตามที่คาดไว้
\d+รูปแบบ 2. ) แปลงสตริงที่ตรงกันเป็นตัวเลขในรหัสของคุณ แล้ว 3. ) if(num >= 0 && num <= 12){ /*do something*/ }ตรวจสอบช่วงจำนวนเช่น เร็วและยืดหยุ่นมาก
ฉันพยายามใช้รูปแบบช่วง[01-12]ใน regex เพื่อจับคู่ mm สองหลัก แต่ไม่ได้ผลตามที่คาดไว้
\d+รูปแบบ 2. ) แปลงสตริงที่ตรงกันเป็นตัวเลขในรหัสของคุณ แล้ว 3. ) if(num >= 0 && num <= 12){ /*do something*/ }ตรวจสอบช่วงจำนวนเช่น เร็วและยืดหยุ่นมาก
คำตอบ:
ดูเหมือนคุณจะเข้าใจผิดว่านิยามคลาสอักขระทำงานอย่างไรใน regex
เพื่อให้ตรงกับใด ๆ ของสตริง01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11หรือ12บางอย่างเช่นงานนี้:
0[1-9]|1[0-2]
คลาสอักขระโดยตัวมันเองจะพยายามจับคู่อักขระหนึ่งตัวจากสตริงอินพุต [01-12]จริงกำหนด[012]เป็นตัวละครคลาสที่ตรงกับตัวละครตัวหนึ่งจากการป้อนข้อมูลกับใด ๆ ของ 3 ตัวอักษร0, หรือ12
-นิยามช่วงไปจาก1การซึ่งรวมถึงเพียง1 1ในทางกลับกันบางอย่างเช่น[1-9]มี1, 2, 3, 4, 5, 6, 7, ,89
[this|that]มือใหม่มักจะทำให้ความผิดพลาดของการกำหนดสิ่งที่ต้องการ สิ่งนี้ไม่ "ได้ผล" นี้กำหนดคำนิยามของตัวละคร[this|a]คือมันตรงกับตัวละครตัวหนึ่งจากการป้อนข้อมูลใด ๆ กับ 6 ตัวอักษรในt, h, i, s, หรือ| aมากกว่าที่จะ(this|that)เป็นไปได้คือสิ่งที่ตั้งใจไว้
ตอนนี้เห็นได้ชัดว่ารูปแบบที่เหมือนbetween [24-48] hoursไม่ได้ "ทำงาน" คลาสอักขระในกรณีนี้เทียบเท่ากับ[248].
นั่นคือ-ในนิยามคลาสอักขระไม่ได้กำหนดช่วงตัวเลขในรูปแบบ เอ็นจิ้น Regex ไม่ "เข้าใจ" ตัวเลขในรูปแบบจริงๆยกเว้นไวยากรณ์การทำซ้ำแบบ จำกัด (เช่นการa{3,5}จับคู่ระหว่าง 3 ถึง 5 a)
การกำหนดช่วงแทนใช้การเข้ารหัส ASCII / Unicode ของอักขระเพื่อกำหนดช่วง อักขระ0ถูกเข้ารหัสใน ASCII เป็นทศนิยม 48 9คือ 57 ดังนั้นนิยามอักขระจึง[0-9]รวมอักขระทั้งหมดที่มีค่าอยู่ระหว่างทศนิยม 48 ถึง 57 ในการเข้ารหัส ค่อนข้างสมเหตุสมผลโดยการออกแบบเหล่านี้เป็นตัวละคร0, 1, ... 9,
มาดูนิยามคลาสอักขระทั่วไปอื่นกัน [a-zA-Z]
ใน ASCII:
A= 65, Z= 90a= 97, z= 122ซึ่งหมายความว่า:
[a-zA-Z]และ[A-Za-z]เทียบเท่า[a-Z]มีแนวโน้มที่จะเป็นช่วงอักขระที่ผิดกฎหมาย
a(97) "มากกว่า" มากกว่าZ(90)[A-z] ถูกกฎหมาย แต่รวมถึงอักขระหกตัวเหล่านี้ด้วย:
[(91), \(92), ](93), ^(94), _(95), `(96)0[1-9]|1[0-2]จะไม่ได้ผล เปลี่ยนไปขั้นตอนต่อไปตรรกะ[1-9]|1[0-2]ไม่ทำงานอย่างใดอย่างหนึ่งด้วยเหตุผลที่เข้าใจได้ (มันตรงกับ1เฉพาะใน10, 11และ12) ก็ต้องใช้\b(?:[0-9]|1[0-1])\bเพื่อป้องกันนั้น \bตรวจสอบให้แน่ใจว่า regex ตรงกับคำ (หรือในกรณีนี้) ขอบเขต ( ^& $ไม่ได้); วงเล็บทำให้หรือ ( |) พิจารณาอีกด้านหนึ่งของมัน และสุดท้าย?:คืออย่าสร้างชุดย่อยด้วยการใช้วงเล็บ
"1,2,3,4,5,6,7,8,9,10,17,18".match(/^(([1-9]|1[0-7])\,?)+$/g )คุณช่วยบอกหน่อยได้ไหมว่าเหตุใด JS regex จึงตรงกับ 17?
คลาสอักขระในนิพจน์ทั่วไปแสดงโดย[...]ไวยากรณ์ระบุกฎเพื่อจับคู่อักขระเดี่ยวในอินพุต เป็นเช่นนี้ทุกสิ่งที่คุณเขียนระหว่างวงเล็บระบุว่าเพื่อให้ตรงกับตัวอักษรตัวเดียว
รูปแบบของคุณ[01-12]แบ่งออกเป็นดังนี้:
โดยพื้นฐานแล้วทั้งหมดที่คุณจับคู่คือ 0, 1 หรือ 2
ในการจับคู่ที่คุณต้องการการจับคู่ตัวเลขสองหลักตั้งแต่ 01-12 เป็นตัวเลขคุณต้องคิดว่าจะมีลักษณะเป็นข้อความอย่างไร
คุณมี:
จากนั้นคุณจะต้องเขียนนิพจน์ทั่วไปสำหรับสิ่งนั้นซึ่งอาจมีลักษณะดังนี้:
+-- a 0 followed by 1-9
|
| +-- a 1 followed by 0-2
| |
<-+--> <-+-->
0[1-9]|1[0-2]
^
|
+-- vertical bar, this roughly means "OR" in this context
โปรดทราบว่าการพยายามรวมเข้าด้วยกันเพื่อให้ได้นิพจน์ที่สั้นลงจะล้มเหลวโดยให้การจับคู่ค่าบวกเท็จสำหรับอินพุตที่ไม่ถูกต้อง
ตัวอย่างเช่น[0-1][0-9]โดยทั่วไปรูปแบบจะตรงกับตัวเลข 00-19 ซึ่งมากกว่าที่คุณต้องการเล็กน้อย
ฉันพยายามหาแหล่งที่มาที่แน่นอนสำหรับข้อมูลเพิ่มเติมเกี่ยวกับชั้นเรียนตัวอักษร แต่สำหรับตอนนี้ทั้งหมดที่ฉันสามารถทำให้คุณเป็นแบบนี้Google คำถามสำหรับ Regex ชั้นเรียนตัวอักษร หวังว่าคุณจะสามารถหาข้อมูลเพิ่มเติมเพื่อช่วยคุณได้
สิ่งนี้ยังใช้งานได้:
^([1-9]|[0-1][0-2])$
[1-9] จับคู่ตัวเลขเดียวระหว่าง 1 ถึง 9
[0-1][0-2] จับคู่ตัวเลขสองหลักระหว่าง 10 ถึง 12
มีตัวอย่างดีๆอยู่ที่นี่
[0-1][0-2]ตรงกัน00ด้วย ที่กล่าวว่า +1 สำหรับลิงก์ (ซึ่งฉันใช้ในคำตอบของฉัน)
[0-1][0-2]ต้องตีความอย่างระมัดระวังเนื่องจากจะช่วยให้สตริงชอบ00, 01และ02แต่ก็ไม่ยอมรับ03ถึง09ยอมรับในที่สุด10, และ11 12regex ที่ถูกต้องสำหรับสิ่งนั้นคือ[1-9]|1[0-2]หรือแม้กระทั่ง0*([1-9]|1[0-2])(สุดท้ายนี้อนุญาตให้มีเลขศูนย์นำหน้าจำนวนเท่าใดก็ได้)
[]ในนิพจน์ทั่วไปแสดงถึงตัวละครคลาส หากไม่มีการระบุช่วงจะเป็นไปโดยปริยายหรือ s ทุกอักขระที่อยู่ในนั้นรวมกัน ดังนั้นจึง[abcde]เหมือนกับ(a|b|c|d|e)ยกเว้นว่าจะไม่จับภาพอะไรเลย มันจะตรงกับคนใดคนหนึ่งของa, b, c, หรือd eทุกช่วงบ่งชี้ว่าเป็นชุดของตัวละคร ; [ac-eg]ระบุว่า "จับคู่aอักขระใดตัวหนึ่งของ: อักขระใดก็ได้ระหว่างcและeหรือg" ดังนั้นการจับคู่ของคุณบอกว่า "ตรงกับคนใดคนหนึ่งของ: 0; ตัวอักษรใด ๆ ระหว่าง1และ1( เช่นเพียง1) 2หรือ
เป้าหมายของคุณคือการระบุช่วงตัวเลข: ตัวเลขใด ๆ ที่อยู่ระหว่าง01และ12เขียนด้วยตัวเลขสองหลัก ในกรณีนี้โดยเฉพาะคุณสามารถจับคู่กับ0[1-9]|1[0-2]: อย่างใดอย่างหนึ่ง0ตามหลักใด ๆ ระหว่าง1และ9หรือ1ตามหลักใด ๆ ระหว่างและ0 2โดยทั่วไปคุณสามารถเปลี่ยนช่วงตัวเลขใด ๆ ให้เป็นนิพจน์ทั่วไปที่ถูกต้องในลักษณะที่คล้ายกัน อย่างไรก็ตามอาจมีตัวเลือกที่ดีกว่านิพจน์ทั่วไปหรือฟังก์ชันหรือโมดูลที่มีอยู่ซึ่งสามารถสร้างนิพจน์ทั่วไปให้คุณได้ ขึ้นอยู่กับภาษาของคุณ
ดังที่ polygenelubricants บอกว่าคุณจะมองหา 0 | 1-1 | 2 มากกว่าสิ่งที่คุณต้องการเนื่องจากคลาสของตัวละคร (สิ่งต่างๆใน []) จับคู่อักขระมากกว่าสตริง
0|1-1|2- สัญกรณ์นี้ทำให้เข้าใจผิดมาก สิ่งที่ต้องการ0|1|2จะถูกต้องมากขึ้น
ใช้สิ่งนี้:
0?[1-9]|1[012]
ในการทดสอบรูปแบบเมื่อ 07/2018 ให้ใช้สิ่งนี้:
/^(0?[1-9]|1[012])\/([2-9][0-9]{3})$/
(ช่วงวันที่ระหว่าง 01/2000 ถึง 12/9999)
[a-z0-9]สิ่งนี้จะจับคู่ตัวอักษรตัวพิมพ์เล็กและตัวเลขทั้งหมด แต่เป็นเพียงอักขระตัวเดียว