ทดสอบ Regex
พิมพ์แพตเทิร์น เลือกแฟล็กที่ต้องการ แล้ววางข้อความลงไป ทุกส่วนที่ตรงกันจะถูกไฮไลต์ทันทีขณะพิมพ์ พร้อมแสดงตำแหน่งและกลุ่มจับของแต่ละรายการ แพตเทิร์นทำงานบนเอนจิน Regex ของ JavaScript ในเบราว์เซอร์ของคุณเอง ผลลัพธ์จึงตรงกับโค้ดของคุณ และข้อความไม่ออกจากอุปกรณ์ของคุณ
0 ตัวอักษร · 0 คำ · 0 บรรทัด
ผลการจับคู่จะถูกไฮไลต์ที่นี่0 ตัวอักษร · 0 คำ · 0 บรรทัด
ทำงานทั้งหมดภายในแท็บเบราว์เซอร์นี้ ข้อความของคุณจะไม่ถูกอัปโหลดหรือจัดเก็บไว้
โทเคน regex ของ JavaScript
คอลัมน์ผลจับคู่แรกได้จากการรันแต่ละรูปแบบกับข้อความของรูปแบบนั้นด้วยเอนจิน JavaScript ที่ใช้สร้างหน้านี้
| โทเคน | ความหมาย | รูปแบบ | ข้อความ | ผลจับคู่แรก |
|---|---|---|---|---|
\d | ตัวเลข 0–9 | /\d+/ | Order 66 shipped | 66 |
\w | ตัวอักษร ตัวเลข หรือขีดล่าง (ASCII) | /\w+/ | snake_case-id | snake_case |
\s | ช่องว่าง รวมถึงแท็บและการขึ้นบรรทัดใหม่ | /\s+/ | two spaces | |
. | อักขระใดก็ได้ยกเว้นการขึ้นบรรทัดใหม่ (เว้นแต่ใช้ s) | /a.c/ | abc a-c | abc |
^ $ | จุดเริ่มต้นและจุดสิ้นสุดของข้อมูลเข้า (หรือของบรรทัด เมื่อใช้ m) | /^\w+$/ | single | single |
[abc] | อักขระตัวใดตัวหนึ่งในรายการ | /[aeiou]/ | rhythm and blues | a |
[^abc] | อักขระใดก็ได้ที่ไม่อยู่ในรายการ | /[^0-9]+/ | 2026-10-18 | - |
* + ? | 0 ครั้งขึ้นไป, 1 ครั้งขึ้นไป, 0 หรือ 1 ครั้ง | /colou?r/ | color colour | color |
{n,m} | ระหว่าง n ถึง m ครั้ง | /\d{2,4}/ | 7 42 1999 123456 | 42 |
(…) | กลุ่มแบบจับค่า (capturing group) | /(\d+)px/ | width: 320px | 320px |
(?<name>…) | กลุ่มแบบจับค่าที่ตั้งชื่อ | /(?<h>\d\d):(?<m>\d\d)/ | at 09:45 | 09:45 |
(?:…) | กลุ่มแบบไม่จับค่า | /(?:ab)+/ | ababab! | ababab |
a|b | ด้านใดด้านหนึ่ง | /cat|dog/ | hotdog | dog |
\b | ขอบเขตของคำ | /\bcat\b/ | concat cat | cat |
(?=…) | ตามด้วย (lookahead) | /\d+(?=%)/ | 50 of 75% | 75 |
(?<!…) | ไม่ได้นำหน้าด้วย (negative lookbehind) | /(?<!\$)\b\d+/ | $30 or 40 | 40 |
\p{L} | ตัวอักษร Unicode ใดก็ได้ (ต้องใช้ u) | /\p{L}+/u | naïve 東京 | naïve |
แฟล็กทั้งหกตัวและผลที่เปลี่ยนไป
g (global) จะหาทุกรายการที่ตรงกัน แทนที่จะหยุดที่รายการแรก หากไม่ใช้ รายการผลลัพธ์จะมีเพียงหนึ่งรายการ i ไม่สนใจตัวพิมพ์เล็กหรือใหญ่ m (multiline) ทำให้ ^ และ $ ตรงกับจุดเริ่มต้นและจุดสิ้นสุดของแต่ละบรรทัด แทนที่จะเป็นของข้อความทั้งหมด ซึ่งเหมาะกับรูปแบบอย่างช่องว่างท้ายบรรทัด s (dotAll เพิ่มใน ES2018) ทำให้ . ตรงกับการขึ้นบรรทัดใหม่ด้วย u (unicode) มองข้อความเป็น code point ดังนั้นอีโมจิจึงนับเป็นหนึ่งอักขระ และเปิดใช้ property escape เช่น \p{L} สำหรับตัวอักษรใดก็ได้ในทุกระบบการเขียน y (sticky) จะตรงกันเฉพาะที่ตำแหน่งปัจจุบันพอดี ซึ่งเป็นโหมดที่ตัวแยกโทเค็นใช้ JavaScript ยังมี d สำหรับดัชนีของผลที่ตรงกัน และ v สำหรับการดำเนินการเซตในคลาส แต่เครื่องมือนี้รองรับเฉพาะหกแฟลกข้างต้น
ใต้ข้อความทดสอบ แต่ละรายการที่ตรงกันจะแสดงดัชนีและกลุ่มของมัน กลุ่มแบบมีหมายเลขมาจากวงเล็บธรรมดา (?:…) เป็นกลุ่มที่ไม่จับค่า และ (?<year>\d{4}) สร้างกลุ่มที่มีชื่อซึ่งแสดงตามชื่อ ดังตัวอย่างวันที่แบบ ISO เมนู รูปแบบที่ใช้บ่อย จะแทรกจุดเริ่มต้นที่ผ่านการทดสอบแล้วสำหรับอีเมล URL ที่อยู่ IPv4 สีเลขฐานสิบหก UUID คำที่ซ้ำกัน และช่องว่างท้ายบรรทัด ให้ใช้รูปแบบอีเมลเป็นเพียงการตรวจเบื้องต้น ไม่ใช่การตรวจสอบจริง เพราะไวยากรณ์ของที่อยู่อีเมลเต็มรูปแบบกว้างกว่านั้นมาก และการทดสอบที่แท้จริงคือการส่งอีเมลไปให้ถึง
Lookbehind และปัญหา Catastrophic Backtracking
Lookaround ใช้ตรวจสิ่งที่อยู่รอบตำแหน่งโดยไม่นำมารวมในผลลัพธ์ Lookahead คือ (?=…) และ (?!…) มีอยู่ใน JavaScript มาตลอด ส่วน lookbehind คือ (?<=…) และ (?<!…) เพิ่มเข้ามาใน ES2018 และรองรับในเบราว์เซอร์หลักทุกตัวเมื่อ Safari 16.4 เปิดตัวในปี 2023 ดังนั้น (?<=\$)\d+ จะหา 42 ใน "$42" โดยไม่รวมเครื่องหมายดอลลาร์ ต่างจากเอนจินอื่นหลายตัว JavaScript อนุญาตให้ lookbehind มีความยาวเท่าใดก็ได้
เอนจินของ JavaScript ทำงานแบบ backtracking คือเมื่อเส้นทางหนึ่งล้มเหลวก็จะย้อนกลับไปลองทางเลือกอื่น Quantifier ซ้อนกันอย่าง (a+)+$ ทำให้มีวิธีแบ่งข้อความเดิมเป็นจำนวนมหาศาลแบบเอกซ์โพเนนเชียล สตริงที่เป็น a 30 ตัวตามด้วย x อาจใช้เวลาหลายวินาที และเพิ่มตัวอักษรอีกไม่กี่ตัวอาจใช้เวลาหลายชั่วโมง นี่คือ catastrophic backtracking และบนเซิร์ฟเวอร์จะกลายเป็น ReDoS หรือการโจมตีแบบปฏิเสธการให้บริการ กฎ WAF เพียงข้อเดียวที่มีข้อบกพร่องนี้เคยทำให้เครือข่ายของ Cloudflare ล่มราวครึ่งชั่วโมงเมื่อวันที่ 2 กรกฎาคม 2019 เนื่องจากเครื่องมือนี้ทำงานในแท็บของคุณ รูปแบบลักษณะนี้จึงอาจทำให้หน้าค้างได้ ให้โหลดหน้าใหม่แล้วเขียนรูปแบบใหม่ไม่ให้ quantifier สองตัวแย่งอักขระเดียวกันได้ โดยใช้คลาสที่แคบลง เช่น [^,]* แทน .* หรือใช้ anchor หากต้องการแก้ไขข้อความเองแทนการจับคู่ ดูที่เครื่องมือข้อความ และยูทิลิตี้สำหรับนักพัฒนาเพิ่มเติมอยู่ที่เครื่องมือสำหรับนักพัฒนา
คำถามที่พบบ่อย
- ทำไม Regex จึงเจอผลที่ตรงกันเพียงรายการเดียว
- แฟลก g ปิดอยู่ หากไม่เปิด เอนจินจะหยุดหลังพบรายการแรก ให้ติ๊ก g เพื่อแสดงทุกรายการ แฟลก y เพียงอย่างเดียวก็พบได้หลายรายการ แต่เฉพาะรายการที่ต่อเนื่องกันโดยตรงเท่านั้น
- ใน JavaScript \d ตรงกับตัวเลขของอักษรภาษาอื่น เช่น เลขไทย หรือไม่
- ไม่ใช่ ใน JavaScript \d หมายถึง 0 ถึง 9 เท่านั้น และ \w หมายถึงตัวอักษร ASCII ตัวเลข และขีดล่างเท่านั้น แม้ใช้แฟลก u ก็ตาม สำหรับระบบการเขียนอื่นให้ใช้ \p{Nd} หรือ \p{L} ร่วมกับ u
- แพตเทิร์นที่ทดสอบที่นี่จะทำงานเหมือนกันใน Python หรือ PHP หรือไม่
- ไวยากรณ์พื้นฐานใช้ร่วมกันได้ แต่รายละเอียดต่างกัน กลุ่มที่มีชื่อของ Python เขียนเป็น
(?P<name>…)PHP และ Python รองรับ possessive quantifier ซึ่ง JavaScript ไม่มี และกฎของ lookbehind ก็แตกต่างกัน ควรทดสอบซ้ำในเอนจินปลายทาง - จะจับคู่จุดหรือวงเล็บตามตัวอักษรได้อย่างไร
- ใส่แบ็กสแลชนำหน้า
\.ตรงกับจุด และ\[ตรงกับวงเล็บเหลี่ยมเปิด ภายในคลาสอักขระ สัญลักษณ์ส่วนใหญ่เป็นอักขระตามตัวอักษรอยู่แล้ว ดังนั้น[.]ก็ตรงกับจุดเท่านั้นเช่นกัน - ทำไมหน้าเว็บค้างขณะกำลังพิมพ์แพตเทิร์น
- รูปแบบนี้น่าจะทำให้เกิด catastrophic backtracking กับข้อความของคุณ ให้โหลดหน้าใหม่ แล้วหลีกเลี่ยง quantifier ซ้อนกัน เช่น
(.*)*หรือ(a+)+และทำให้แต่ละส่วนตรงกับอักขระให้น้อยที่สุดเท่าที่ทำได้