ข้ามไปยังเนื้อหา
LeedyBox
สนับสนุน

พื้นฐานนิพจน์ปกติ

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

อักขระตามตัวและคลาสอักขระ

อักขระส่วนใหญ่ตรงกับตัวมันเอง แพตเทิร์น cat จะพบข้อความ "cat" อักขระบางตัวมีความหมายพิเศษ เช่น . * + ? ( ) [ ] { } ^ $ | \ หากต้องการจับคู่อักขระเหล่านี้ตามตัวอักษร ให้ escape ด้วยแบ็กสแลช เช่น \. สำหรับจุด

คลาสอักขระจับคู่อักขระหนึ่งตัวจากชุดที่กำหนด [abc] ตรงกับ a, b หรือ c ส่วน [a-z] ตรงกับตัวอักษร ASCII พิมพ์เล็ก และ [^0-9] ตรงกับอะไรก็ได้ที่ไม่ใช่ตัวเลข รูปย่อที่ใช้บ่อยได้แก่ \d (ตัวเลข) \w (ตัวอักษร ตัวเลข หรือขีดล่าง) \s (ช่องว่าง) และรูปตรงข้าม \D, \W และ \S จุด . ตรงกับอักขระใดก็ได้ยกเว้นการขึ้นบรรทัดใหม่

ใน JavaScript \w และ \d ครอบคลุมเฉพาะอักขระ ASCII หากต้องการจับคู่ตัวอักษรของทุกภาษา ให้ใช้ Unicode property เช่น \p{L} ร่วมกับแฟล็ก u

ตัวระบุจำนวนและตัวยึดตำแหน่ง

ตัวระบุจำนวนบอกว่ารายการก่อนหน้าซ้ำได้กี่ครั้ง

ไวยากรณ์ความหมายตัวอย่าง
*0 ครั้งขึ้นไปab* ตรงกับ a, ab, abbb
+1 ครั้งขึ้นไป\d+ ตรงกับ 7 หรือ 2026
?0 หรือ 1 ครั้งcolou?r ตรงกับ color และ colour
{n,m}ระหว่าง n ถึง m ครั้ง\d{2,4} ตรงกับตัวเลข 2 ถึง 4 หลัก

ตัวยึดตำแหน่งจับคู่ตำแหน่งแทนที่จะเป็นอักขระ ^ คือจุดเริ่มต้น และ $ คือจุดสิ้นสุดของข้อมูลเข้า (หรือของแต่ละบรรทัดเมื่อใช้แฟล็ก m) \b คือขอบคำ ดังนั้น \bcat\b จะพบ "cat" แต่ไม่พบใน "concatenate" เมื่อตรวจสอบค่าทั้งค่า ให้ยึดทั้งสองด้าน เช่น ^\d{5}$ รับเฉพาะตัวเลขห้าหลักพอดีเท่านั้น

กลุ่มและการจับ

วงเล็บใช้รวมส่วนหนึ่งของแพตเทิร์นเป็นกลุ่ม เพื่อให้ตัวระบุจำนวนหรือทางเลือกมีผลกับส่วนนั้น (ab)+ ทำซ้ำ "ab" และ (jpg|png) ตรงกับคำใดคำหนึ่ง กลุ่มปกติยังจับข้อความที่ตรงไว้ด้วย ซึ่งนำไปใช้ซ้ำในการแทนที่ได้เป็น $1, $2 และต่อไปเรื่อย ๆ

กลุ่มที่มีชื่อ เช่น (?<year>\d{4}) ทำให้แพตเทิร์นอ่านง่ายขึ้น และอ้างอิงได้เป็น $<year> หากต้องการเพียงการจัดกลุ่ม กลุ่มที่ไม่จับ (?:...) จะช่วยไม่ให้เกิดการจับที่ไม่ได้ใช้ เครื่องมือทดสอบ RegEx ของ LeedyBox แสดงส่วนที่ตรงแต่ละรายการพร้อมกลุ่มที่จับได้ และแสดงตัวอย่างการแทนที่

แฟล็ก

แฟล็กเปลี่ยนพฤติกรรมของทั้งแพตเทิร์น แฟล็กของ JavaScript ที่ใช้บ่อยได้แก่

  • g (global): ค้นหาทุกส่วนที่ตรง แทนที่จะหาเฉพาะส่วนแรก
  • i (ignore case): ถือว่าตัวพิมพ์ใหญ่และตัวพิมพ์เล็กเหมือนกัน
  • m (multiline): ^ และ $ ตรงที่การขึ้นบรรทัดใหม่แต่ละครั้ง
  • s (dotAll): . ตรงกับการขึ้นบรรทัดใหม่ด้วย
  • u (unicode): เปิดใช้การจับคู่ที่รองรับ Unicode และคลาส \p{...}

JavaScript ยังมี y (sticky) และ d (ตำแหน่งของส่วนที่ตรง) ซึ่งเครื่องมือทดสอบก็รองรับเช่นกัน

Greedy กับ Lazy และ Catastrophic Backtracking

ตามค่าเริ่มต้น ตัวระบุจำนวนเป็นแบบ greedy คือจับคู่ให้มากที่สุดเท่าที่ทำได้ แล้วค่อยคืนอักขระทีละตัวหากส่วนที่เหลือของแพตเทิร์นไม่ตรง กับข้อความ <b>bold</b> แพตเทิร์น <.+> จะตรงกับทั้งสตริง การเติม ? ทำให้ตัวระบุจำนวนเป็นแบบ lazy ดังนั้น <.+?> จะตรงกับ <b> เพียงอย่างเดียว คลาสแบบปฏิเสธ เช่น <[^>]+> มักชัดเจนกว่าและเร็วกว่า

เอนจิน regex ส่วนใหญ่ รวมถึงของ JavaScript ใช้ backtracking ตัวระบุจำนวนซ้อนกันอย่าง (a+)+$ หรือทางเลือกที่ทับซ้อนกัน อาจทำให้เอนจินลองชุดค่าผสมจำนวนมหาศาลเมื่อจับคู่ไม่สำเร็จ ซึ่งอาจทำให้หน้าเว็บหรือเซิร์ฟเวอร์ค้าง ปัญหานี้เรียกว่า catastrophic backtracking และเมื่อใช้กับข้อมูลเข้าที่ไม่น่าเชื่อถือ อาจถูกนำไปใช้โจมตีแบบปฏิเสธการให้บริการ (ReDoS) ได้ หลีกเลี่ยงการซ้อนตัวระบุจำนวนบนอักขระชุดเดียวกัน เลือกใช้คลาสที่เจาะจงแทน .* และทดสอบแพตเทิร์นกับข้อมูลเข้ายาว ๆ ที่ไม่ตรง

Regex แต่ละแบบต่างกัน

regex ไม่มีมาตรฐานเดียว JavaScript, Python, Java, .NET, PCRE (ที่ PHP ใช้), Go และฐานข้อมูลต่าง ๆ รองรับไวยากรณ์ที่ต่างกันเล็กน้อย lookbehind, possessive quantifier, ไวยากรณ์กลุ่มที่มีชื่อ คลาส Unicode และไวยากรณ์การแทนที่แตกต่างกันไป ตัวอย่างเช่น เอนจิน RE2 ของ Go ไม่รองรับ lookaround และการอ้างอิงย้อนกลับ

เครื่องมือทดสอบ RegEx ของ LeedyBox ใช้เอนจิน JavaScript ของเบราว์เซอร์ แพตเทิร์นที่ใช้ได้ที่นั่นอาจต้องปรับแก้ในภาษาอื่น จึงควรทดสอบอีกครั้งในที่ที่จะรันจริง

คำถามที่พบบ่อย

ทำไมแพตเทิร์นของฉันจึงตรงเฉพาะตำแหน่งแรก

หากไม่มีแฟล็ก g JavaScript จะหยุดหลังจากพบส่วนที่ตรงส่วนแรก ให้เปิดแฟล็ก g เพื่อค้นหาทุกส่วนที่ตรง

regex ตรวจสอบที่อยู่อีเมลได้หรือไม่

regex ตรวจได้ว่าค่ามีลักษณะที่เป็นไปได้หรือไม่ แต่ยืนยันไม่ได้ว่าที่อยู่นั้นมีอยู่จริง วิธีที่ใช้กันทั่วไปในการยืนยันคือการส่งอีเมลยืนยัน

ทำไม ^ จึงตรงเพียงครั้งเดียวในข้อความหลายบรรทัด

ตามค่าเริ่มต้น ^ และ $ หมายถึงข้อมูลเข้าทั้งหมด ให้เปิดแฟล็ก m เพื่อให้ตรงที่ต้นและท้ายของแต่ละบรรทัด