blog.dopana

Back

Regex (Regular Expression) là pattern để tìm kiếm và thao tác với chuỗi. Khó học lần đầu — nhưng một khi hiểu, bạn tiết kiệm hàng giờ xử lý text thủ công.

Cơ Bản — Các Pattern Thường Dùng#

Literal Characters#

/hello/      → Tìm "hello"
/hello123/   → Tìm "hello123"
regex

Meta Characters#

.   → Bất kỳ ký tự nào (trừ newline)
\d  → Digit (0-9)
\w  → Word character (a-z, A-Z, 0-9, _)
\s  → Whitespace (space, tab, newline)
\b  → Word boundary
^   → Đầu chuỗi
$   → Cuối chuỗi
regex

Quantifiers#

*   → 0 hoặc nhiều lần
+   → 1 hoặc nhiều lần
?   → 0 hoặc 1 lần
{3} → Đúng 3 lần
{2,4} → 2 đến 4 lần
{2,} → Ít nhất 2 lần
regex

Character Classes#

[abc]     → a, b, hoặc c
[a-z]     → a đến z
[^abc]    → Không phải a, b, c
[0-9]     → 0 đến 9
[a-zA-Z]  → a-z hoặc A-Z
regex

Ví Dụ Thực Tế#

Validate Email#

/^[^\s@]+@[^\s@]+\.[^\s@]+$/
regex
function isValidEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
typescript

Giải thích:

  • ^ — đầu chuỗi
  • [^\s@]+ — 1+ ký tự không phải space hoặc @
  • @ — literal @
  • [^\s@]+ — domain name
  • \. — literal dấu chấm
  • [^\s@]+ — TLD
  • $ — cuối chuỗi

Trích Xuất URL#

/https?:\/\/[^\s]+/g
regex
function extractUrls(text: string): string[] {
  return text.match(/https?:\/\/[^\s]+/g) || [];
}
typescript

Validate Số Điện Thoại Việt Nam#

/(84|0)[3|5|7|8|9]\d{8}/
regex
  • (84|0) — đầu 84 hoặc 0
  • [3|5|7|8|9] — nhà mạng
  • \d{8} — 8 số

Tìm Password Mạnh#

/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/
regex

Lookahead assertions (?=...) — kiểm tra có chứa:

  • (?=.*[a-z]) — có chữ thường
  • (?=.*[A-Z]) — có chữ hoa
  • (?=.*\d) — có số
  • (?=.*[!@#$%^&*]) — có ký tự đặc biệt
  • .{8,} — ít nhất 8 ký tự

Format Số Điện Thoại#

// 0987654321 → 0987 654 321
const phone = '0987654321';
const formatted = phone.replace(/(\d{4})(\d{3})(\d{3})/, '$1 $2 $3');
typescript

Trim Whitespace#

// Thay vì .trim()
const trimmed = text.replace(/^\s+|\s+$/g, '');
typescript

Extract Hashtag#

function extractHashtags(text: string): string[] {
  return text.match(/#\w+/g)?.map(t => t.slice(1)) || [];
}
// "Hello #world #regex" → ["world", "regex"]
typescript

Slugify#

function slugify(text: string): string {
  return text
    .toLowerCase()
    .replace(/[^\w\s-]/g, '')  // Xoá ký tự đặc biệt
    .replace(/[\s_]+/g, '-')   // Space → dash
    .replace(/^-+|-+$/g, '');  // Xoá dash đầu cuối
}
// "Hello World!" → "hello-world"
typescript

Regex Trong VS Code#

Tìm kiếm nâng cao với regex:

Tìm:     function\s+(\w+)\s*\(
Thay:    export function $1(
→ Thêm export vào tất cả function

Tìm:     console\.log\(.*\);
Thay:    (xóa)
→ Xoá toàn bộ console.log
text

Regex Flag#

/g  → Global — tìm tất cả, không chỉ kết quả đầu
/i  → Case insensitive — không phân biệt hoa thường
/m  → Multiline — ^$ match từng dòng
/s  → Dotall — . match cả newline
/u  → Unicode — hỗ trợ unicode
/y  → Sticky — match từ vị trí lastIndex
regex

Performance — Đừng Viết Regex Quá Tệ#

// ❌ Tệ — catastrophic backtracking
/<([A-Z]+)>.*<\/\1>/

// ✅ Tốt — atomic group / possessive quantifier
/<([A-Z]+)>[^<]*<\/\1>/

// Tránh nested quantifiers: (a+)+, (a|b)*, ...
// Chúng có thể gây backtracking mất hàng phút
regex

Debug Regex#

Công cụ online:

  • regex101.com — giải thích từng token, test online
  • regexr.com — cheatsheet, test
  • debuggex.com — trực quan hoá dưới dạng sơ đồ

Cheatsheet Nhanh#

Kết Luận#

Regex không cần nhớ hết — chỉ cần nhớ các pattern cơ bản và biết cách tra cứu. Luôn dùng regex101.com để test. Performance quan trọng — tránh backtracking với chuỗi dài. Bắt đầu với 5 pattern: email, URL, số điện thoại, trim whitespace, extract.

Tài liệu tham khảo#