นิพจน์ปกติ (regex) เป็นวิธีอธิบายรูปแบบข้อความอย่างกระชับ — ไม่ใช่สตริงที่เจาะจง แต่เป็นกฎที่สตริงต้องสอดคล้องด้วย แทนที่จะวนลูปตรวจทีละตัวอักษร สามารถใช้นิพจน์เดียวตรวจสอบหรือค้นหาโครงสร้างที่ซับซ้อนได้
ส่วนประกอบพื้นฐาน
- คลาสอักขระ —
\d(ตัวเลข),\w(ตัวอักษร/ตัวเลข/ขีดล่าง),\s(ช่องว่าง), หรือคลาสกำหนดเองอย่าง[a-zA-Z] - ตัวระบุจำนวน —
*(0 ครั้งขึ้นไป),+(1 ครั้งขึ้นไป),?(0 หรือ 1 ครั้ง),{2,5}(2 ถึง 5 ครั้ง) - กลุ่มจับคู่ (capture group) — วงเล็บ
(...)ทำเครื่องหมายส่วนหนึ่งของผลลัพธ์ที่ตรงกัน เพื่อนำไปใช้แยกต่างหากได้ เช่นตอนแทนที่ข้อความ - สมอ (anchor) —
^และ$ยึดรูปแบบไว้กับจุดเริ่มต้นหรือจุดสิ้นสุดของบรรทัด
ทำไม \w จึงมองไม่เห็นภาษาไทย
ในเอนจิน regex ของ JavaScript ที่เครื่องมือนี้ใช้ \w หมายถึง [A-Za-z0-9_] เท่านั้นเสมอ — ตัวอักษรละติน ตัวเลข และขีดล่าง ไม่รวมอักษรไทยแม้แต่ตัวเดียว ดังนั้น /^\w+$/.test('สวัสดี') จะคืนค่า false ทันที การเพิ่มแฟล็ก u ก็ไม่ได้ขยายความหมายของ \w แต่อย่างใด หากต้องการจับข้อความภาษาไทยให้ถูกต้อง ต้องใช้คลาสที่อิงคุณสมบัติ Unicode โดยตรง เช่น /^[\p{L}\p{M}]+$/u โดย \p{L} ครอบคลุมพยัญชนะและสระ ส่วน \p{M} จำเป็นสำหรับวรรณยุกต์และสระที่เป็นเครื่องหมายประกอบ (combining mark) ซึ่งแยกจากตัวอักษรฐานในระดับโค้ดพอยต์
การจับคู่แบบโลภกับแบบขี้เกียจ
โดยค่าเริ่มต้น ตัวระบุจำนวนจะ "โลภ" — พยายามจับตัวอักษรให้ได้มากที่สุด และยอมถอยก็ต่อเมื่อสิ่งนั้นขัดขวางการจับคู่ ตัวอย่างเช่น <.+> บนสตริง <a>text</a> จะจับทุกอย่างตั้งแต่ < ตัวแรกไปจนถึง > ตัวสุดท้าย การเติม ? ต่อท้ายตัวระบุจำนวน (<.+?>) จะทำให้มันกลายเป็น "ขี้เกียจ" — จับให้น้อยที่สุดเท่าที่จะเป็นไปได้ และหยุดที่การจับคู่ที่ถูกต้องแรกสุด
ใช้ทำอะไรได้บ้าง
- ตรวจสอบรูปแบบข้อมูลนำเข้า (อีเมล เบอร์โทรศัพท์ รหัสไปรษณีย์)
- ค้นหาและแทนที่ข้อความจำนวนมากตามรูปแบบ แทนการจับคู่แบบตรงเป๊ะ
- ดึงข้อมูลที่มีโครงสร้างออกจากล็อกหรือข้อความที่ไม่มีโครงสร้าง
Backtracking แบบหายนะ
ตัวระบุจำนวนที่ซ้อนกันอย่าง (a+)+ อาจบังคับให้เอนจิน regex ลองชุดค่าผสมจำนวนมหาศาลแบบเอ็กซ์โพเนนเชียลก่อนจะสรุปว่าไม่มีการจับคู่ในบางอินพุต — หน้าเว็บหรือเซิร์ฟเวอร์ "ค้าง" กับนิพจน์ที่ดูเรียบง่าย นี่คือช่องโหว่จริง (ReDoS) ดังนั้นตัวระบุจำนวนซ้อนกันที่ซับซ้อนควรทดสอบกับสตริงยาวที่ "เกือบตรงกัน" ด้วย ไม่ใช่แค่ตัวอย่างที่คาดหวังไว้เท่านั้น