Regex เบื้องต้น — Pattern ที่ใช้บ่อยในงาน Dev
ถ้าคุณเคยเห็นโค้ดแบบ /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i แล้วรู้สึกหัวร้อน — บทความนี้เขียนเพื่อคุณโดยเฉพาะ Regular Expressions หรือ Regex คือภาษาสำหรับค้นหาและตรวจสอบ pattern ในข้อความ เรียนรู้ครั้งเดียว ใช้ได้ทุก language
Regex ใช้ได้กับ
JavaScript, Python, PHP, Go, Java, Ruby, Rust, SQL — และแทบทุก language ที่มีอยู่ ไวยากรณ์ต่างกันนิดหน่อย แต่ core concept เหมือนกัน
ส่วนประกอบของ Regex
Regex ประกอบด้วยชิ้นส่วนหลัก 5 ประเภท — เมื่อรู้ว่าแต่ละส่วนทำงานอย่างไร จะอ่าน pattern ที่ซับซ้อนได้ทันที
^ $
Anchors
Anchors
[a-z] \d \w
Character Classes
Character Classes
* + ? {n,m}
Quantifiers
Quantifiers
( ) (?:)
Groups
Groups
. | \
Special Chars
Special Chars
Anchors — ตำแหน่งใน String
| Symbol | ความหมาย | ตัวอย่าง |
|---|---|---|
^ | ต้นบรรทัด / ต้น string | ^Hello → ตรงกับ "Hello world" |
$ | ท้ายบรรทัด / ท้าย string | end$ → ตรงกับ "the end" |
\b | Word boundary | \bcat\b → "cat" แต่ไม่ใช่ "catch" |
\B | Non-word boundary | \Bcat → ตรงกับ "catch" |
Character Classes — ระบุตัวอักษร
| Pattern | ความหมาย | เทียบเท่า |
|---|---|---|
\d | ตัวเลข 0–9 | [0-9] |
\D | ไม่ใช่ตัวเลข | [^0-9] |
\w | ตัวอักษร, ตัวเลข, underscore | [a-zA-Z0-9_] |
\W | ไม่ใช่ word character | [^a-zA-Z0-9_] |
\s | Whitespace (space, tab, newline) | [ \t\r\n\f] |
\S | ไม่ใช่ whitespace | — |
. | ทุกตัวอักษร ยกเว้น newline | — |
[abc] | a หรือ b หรือ c | — |
[^abc] | ไม่ใช่ a, b, c | — |
[a-z] | ตัวอักษร a ถึง z | — |
Quantifiers — จำนวนครั้ง
| Symbol | ความหมาย | ตัวอย่าง |
|---|---|---|
* | 0 ครั้งขึ้นไป | a* → "", "a", "aaa" |
+ | 1 ครั้งขึ้นไป | a+ → "a", "aaa" (ต้องมีอย่างน้อย 1) |
? | 0 หรือ 1 ครั้ง (optional) | colou?r → "color" หรือ "colour" |
{n} | ตรงกับ n ครั้ง | \d{4} → "2024" |
{n,} | n ครั้งขึ้นไป | \d{2,} → "12", "123456" |
{n,m} | n ถึง m ครั้ง | \d{2,4} → "12", "123", "1234" |
Greedy vs Lazy
Quantifiers แบบ
* และ + เป็น greedy — match ให้มากที่สุด หากต้องการ lazy ให้เติม ?: .*? จะ match น้อยที่สุด เท่าที่จำเป็น
Groups และ Alternation
| Syntax | ความหมาย |
|---|---|
(abc) | Capturing group — จับค่าไว้ใน $1, $2 ... |
(?:abc) | Non-capturing group — จัดกลุ่มแต่ไม่จับค่า |
(?<name>abc) | Named capturing group |
a|b | a หรือ b (alternation) |
(?=abc) | Positive lookahead — ตามด้วย abc |
(?!abc) | Negative lookahead — ไม่ตามด้วย abc |
Pattern ที่ใช้บ่อยในงานจริง
Email Validation
// JavaScript
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
emailRegex.test('[email protected]'); // true
emailRegex.test('invalid@'); // false
emailRegex.test('no-at-sign.com'); // false
เบอร์โทรศัพท์ไทย
// รองรับ: 0812345678 | 081-234-5678 | +66812345678
const thPhoneRegex = /^(\+66|0)([689]\d{8}|[2-8]\d{7})$/;
// แบบง่าย (แค่ตรวจ format 10 หลัก)
const simplePhone = /^0[689]\d{8}$/;
URL
const urlRegex = /^https?:\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/i;
urlRegex.test('https://madestool.com'); // true
urlRegex.test('http://example.com/path?q=1'); // true
urlRegex.test('ftp://old-protocol'); // false
Password (แข็งแรง)
// อย่างน้อย 8 ตัว, มีตัวใหญ่, ตัวเล็ก, ตัวเลข, อักขระพิเศษ
const strongPwd = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
// แยก lookaheads เพื่อให้อ่านง่าย
function checkPassword(pwd) {
const checks = {
length: pwd.length >= 8,
lower: /[a-z]/.test(pwd),
upper: /[A-Z]/.test(pwd),
digit: /\d/.test(pwd),
special:/[@$!%*?&]/.test(pwd)
};
return Object.values(checks).every(Boolean);
}
เลขบัตรประชาชนไทย (13 หลัก)
const thIDRegex = /^\d{13}$/;
// หรือแบบมี dash: 0-0000-00000-00-0
const thIDWithDash = /^\d{1}-\d{4}-\d{5}-\d{2}-\d{1}$/;
IPv4 Address
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
// แบบตรวจค่า 0-255 ด้วย
const strictIPv4 = /^(25[0-5]|2[0-4]\d|[01]?\d\d?)(\.(25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/;
ดึงตัวเลขจาก String
const text = "ราคา 1,299 บาท ลด 20%";
const numbers = text.match(/[\d,]+/g);
// → ["1,299", "20"]
// ดึงเฉพาะตัวเลข (ไม่มีจุลภาค)
text.replace(/[^\d]/g, ''); // "129920"
Flags ที่ใช้บ่อย
| Flag | ความหมาย | JS / Python |
|---|---|---|
i | Case insensitive | /abc/i / re.IGNORECASE |
g | Global (find all matches) | /abc/g / re.findall() |
m | Multiline (^ $ per line) | /abc/m / re.MULTILINE |
s | Dot matches newline too | /abc/s / re.DOTALL |
Python Regex Quickstart
import re
text = "Email: [email protected], [email protected]"
emails = re.findall(r'[\w.+-]+@[\w-]+\.[\w.]+', text)
# → ['[email protected]', '[email protected]']
# Named groups
m = re.match(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})', '2024-12-25')
m.group('year') # '2024'
m.group('month') # '12'
เคล็ดลับการเขียน Regex ที่ดี
- เริ่มจาก test case — นึกถึงตัวอย่างที่ should match และ should not match ก่อนเขียน
- ใช้ non-capturing group
(?:)เมื่อจัดกลุ่มแต่ไม่ต้องการค่า — เร็วกว่าและอ่านง่ายกว่า - อย่า over-engineer — ถ้า string library ทำได้ (split, includes, startsWith) ไม่ต้องใช้ regex
- Comment regex — ภาษาที่รองรับ verbose mode ควร comment ทุก part
- ทดสอบ edge cases — empty string, unicode, special characters, very long strings
Regex Cheat Sheet ด่วน
^ ต้น | $ ท้าย | \d เลข | \w อักษร | \s space | . ทุกตัว | * 0+ | + 1+ | ? 0–1 | {n,m} n–m ครั้ง | () group | | หรือ | [abc] ชุดตัวอักษร | [^abc] ยกเว้น
ทดสอบ Regex แบบ Live
ใส่ pattern และ string — เห็นผลการ match ทันที พร้อม highlight
เปิด Regex Tester →