ตัวทดสอบ Regex
ทดสอบ regular expressions กับข้อความและดูผลการจับคู่ที่เน้นสีทั้งหมด
รูปแบบ
ข้อความทดสอบ
Regular Expression คืออะไร?
Regular expression (regex หรือ regexp) คือลำดับอักขระที่กำหนดรูปแบบการค้นหา ตัวทดสอบ regex ช่วยให้คุณเขียนรูปแบบ รันกับข้อความตัวอย่าง และดูผลการจับคู่ที่เน้นสีแบบเรียลไทม์ แนวคิดนี้มีต้นกำเนิดจากงานของนักคณิตศาสตร์ Stephen Kleene เกี่ยวกับ regular languages ในช่วงทศวรรษ 1950 และ Ken Thompson ได้สร้าง regex engine ตัวแรกไว้ในโปรแกรมแก้ไขข้อความ QED ในปี 1968
Regex engine อ่านรูปแบบจากซ้ายไปขวา โดยใช้อักขระจากข้อความที่รับเข้ามาขณะพยายามจับคู่ เมื่อการจับคู่บางส่วนล้มเหลว engine จะย้อนกลับและลองเส้นทางอื่นในรูปแบบ บาง engine (เช่น RE2 ที่ใช้ใน Go) หลีกเลี่ยงการย้อนกลับโดยสิ้นเชิงด้วยการแปลงรูปแบบเป็น deterministic finite automata (DFA) ซึ่งรับประกันการจับคู่ในเวลาเชิงเส้น แต่ไม่รองรับคุณสมบัติอย่าง back-references
ไวยากรณ์ regex ถูกกำหนดมาตรฐานอย่างหลวมๆ PCRE (Perl Compatible Regular Expressions) เป็นรูปแบบที่พบบ่อยที่สุด รองรับโดย PHP, โมดูล re ของ Python และ JavaScript โดยมีความแตกต่างเล็กน้อย POSIX กำหนดไวยากรณ์ที่จำกัดกว่าซึ่งใช้โดย grep และ sed ความแตกต่างเหล่านี้สำคัญเมื่อนำรูปแบบไปใช้ระหว่างภาษาต่างๆ: lookahead ที่ทำงานได้ใน JavaScript อาจคอมไพล์ไม่ได้เลยใน RE2 engine ของ Go
ทำไมต้องใช้ตัวทดสอบ Regex ออนไลน์?
การเขียน regex ในไฟล์โค้ดหมายถึงต้องบันทึก รัน และตรวจสอบผลลัพธ์ทุกครั้งที่ปรับรูปแบบ ตัวทดสอบ regex บนเบราว์เซอร์ขจัดวงจรป้อนกลับนั้นเป็นศูนย์: พิมพ์แล้วเห็นผลทันที
กรณีการใช้งานตัวทดสอบ Regex
ตารางอ้างอิงไวยากรณ์ Regex
ตารางด้านล่างครอบคลุม token ของ regex ที่ใช้บ่อยที่สุด ใช้ได้กับ JavaScript, Python, Go, PHP และ engine ที่เข้ากันได้กับ PCRE ส่วนขยายเฉพาะภาษา (เช่น conditional pattern ของ Python หรือ named group ของ JavaScript ด้วยไวยากรณ์ \k) จะอธิบายในส่วนตัวอย่างโค้ด
| รูปแบบ | ชื่อ | คำอธิบาย |
|---|---|---|
| . | Any character | Matches any single character except newline (unless s flag is set) |
| \d | Digit | Matches [0-9] |
| \w | Word character | Matches [a-zA-Z0-9_] |
| \s | Whitespace | Matches space, tab, newline, carriage return, form feed |
| \b | Word boundary | Matches the position between a word character and a non-word character |
| ^ | Start of string/line | Matches the start of the input; with m flag, matches start of each line |
| $ | End of string/line | Matches the end of the input; with m flag, matches end of each line |
| * | Zero or more | Matches the preceding token 0 or more times (greedy) |
| + | One or more | Matches the preceding token 1 or more times (greedy) |
| ? | Optional | Matches the preceding token 0 or 1 time |
| {n,m} | Quantifier range | Matches the preceding token between n and m times |
| () | Capturing group | Groups tokens and captures the matched text for back-references |
| (?:) | Non-capturing group | Groups tokens without capturing the matched text |
| (?=) | Positive lookahead | Matches a position followed by the given pattern, without consuming it |
| (?<=) | Positive lookbehind | Matches a position preceded by the given pattern, without consuming it |
| [abc] | Character class | Matches any one of the characters inside the brackets |
| [^abc] | Negated class | Matches any character not inside the brackets |
| | | Alternation | Matches the expression before or after the pipe |
อธิบาย Flag ของ Regex
Flag (หรือที่เรียกว่า modifier) เปลี่ยนวิธีที่ engine ประมวลผลรูปแบบ ใน JavaScript คุณต่อท้าย flag หลัง slash ปิด: /pattern/gi ใน Python คุณส่ง flag เป็นอาร์กิวเมนต์ที่สอง: re.findall(pattern, text, re.IGNORECASE | re.MULTILINE) ไม่ใช่ทุก flag ที่มีในทุกภาษา
| Flag | ชื่อ | พฤติกรรม |
|---|---|---|
| g | Global | Find all matches, not just the first one |
| i | Case-insensitive | Letters match both uppercase and lowercase |
| m | Multiline | ^ and $ match start/end of each line, not just the whole string |
| s | Dot-all | . matches newline characters as well |
| u | Unicode | Treat the pattern and subject as a Unicode string; enables \u{FFFF} syntax |
| y | Sticky | Matches only from the lastIndex position in the target string |
ตัวอย่างโค้ด
ตัวอย่าง regex ที่ใช้งานได้จริงใน JavaScript, Python, Go และ command line แต่ละตัวอย่างแสดงการสร้างรูปแบบ การดึงผลการจับคู่ และผลลัพธ์
// Match all email addresses in a string
const text = 'Contact us at support@example.com or sales@example.com'
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g
const matches = text.matchAll(emailRegex)
for (const match of matches) {
console.log(match[0], 'at index', match.index)
}
// → "support@example.com" at index 14
// → "sales@example.com" at index 37
// Named capture groups (ES2018+)
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const result = '2026-03-30'.match(dateRegex)
console.log(result.groups)
// → { year: "2026", month: "03", day: "30" }
// Replace with a callback
'hello world'.replace(/\b\w/g, c => c.toUpperCase())
// → "Hello World"import re
# Find all IPv4 addresses
text = 'Server 192.168.1.1 responded, fallback to 10.0.0.255'
pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
matches = re.findall(pattern, text)
print(matches) # → ['192.168.1.1', '10.0.0.255']
# Named groups and match objects
date_pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
m = re.search(date_pattern, 'Released on 2026-03-30')
if m:
print(m.group('year')) # → '2026'
print(m.group('month')) # → '03'
# Compile for repeated use (faster in loops)
compiled = re.compile(r'\b[A-Z][a-z]+\b')
words = compiled.findall('Hello World Foo bar')
print(words) # → ['Hello', 'World', 'Foo']package main
import (
"fmt"
"regexp"
)
func main() {
// Find all matches
re := regexp.MustCompile(`\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b`)
text := "Contact support@example.com or sales@example.com"
matches := re.FindAllString(text, -1)
fmt.Println(matches)
// → [support@example.com sales@example.com]
// Named capture groups
dateRe := regexp.MustCompile(`(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})`)
match := dateRe.FindStringSubmatch("2026-03-30")
for i, name := range dateRe.SubexpNames() {
if name != "" {
fmt.Printf("%s: %s\n", name, match[i])
}
}
// → year: 2026
// → month: 03
// → day: 30
// Replace with a function
result := re.ReplaceAllStringFunc(text, func(s string) string {
return "[REDACTED]"
})
fmt.Println(result)
// → Contact [REDACTED] or [REDACTED]
}# Find lines matching an IP address pattern
grep -E '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' access.log
# Extract email addresses from a file
grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' contacts.txt
# Replace dates from YYYY-MM-DD to DD/MM/YYYY using sed
echo "2026-03-30" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
# → 30/03/2026
# Count matches per file in a directory
grep -rcE 'TODO|FIXME|HACK' src/
# → src/main.js:3
# → src/utils.js:1