Regex Expression
Có một bài viết từng viết: “Nếu bạn biết regex thì đời bạn sẽ bớt khổ”. Và nó rất đúng.
Mình từng vất vả vật lộn với đống dữ liệu ngày tháng từa lưa định dạng, mình bị stress và mất rất nhiều thời gian để convert chúng. Phải chi mình biết cái này sớm hơn thì mình đã bớt khổ rồi.
Mình phải làm shortcode trong laravel như wordpress vì laravel không có sẵn, mình phải đi detect ra nó. Nếu không có regex thì thật là vất vả.
Trường hợp tiếp theo là validate, ôi thôi thật sự sợ nếu không có regex.
Vậy regex là gì?
Regex là biểu thức chính quy, giúp mình tìm một chuẩn trong chuỗi rất dễ dàng.
1. Cách viết
1.1 Ký tự thường
STT | Biểu thức | Mô tả | Ghi chú |
---|---|---|---|
01 | a|b | Khớp với a hoặc b | |
02 | [0-9] | Khớp với một trong số từ 0 tới 9 | |
03 | [a-z] | Khớp với một trong chữ từ a tới z | |
04 | [abc] | Có thể khớp với a, b hoặc c | |
05 | [^abc] | Khớp với bất kì kí tự nào ngoài a, b và c | Nếu ^ xuất hiện đầu tiên sau ngoặc vuông, nó có nghĩa là phủ định |
06 | \d | Số bất kì | Thay thế cho [0-9] |
07 | \D | Ký tự không phải là số | Thay thế cho [^0-9] |
08 | \s |
Kí tự khoảng trắng Khớp với dấu trắng bất kỳ(dấu cách, \t,\n) |
|
09 | \S | Không phải kí tự khoẳng trắng | Thay thế cho [^\s] |
10 | \S+ | Một số kí tự không phải khoẳng trắng | Một hoặc một số |
11 | \w | Kí tự chữ |
Thay thế cho [a-zA-Z0-9] Khớp với các chữ cái tiếng anh, chữ số và dấu _ |
12 | \W | Kí tự không phải chữ | Thay thế cho [^\w] |
13 | \b | Ký tự thuộc a-z hoặc A-Z hoặc 0-9 hoặc _ | Thay thế cho [a-zA-Z0-9_] |
14 | \t | Khớp với dấu tab | |
\n | Khớp với new line(xuống hàng) |
1.2 Ký tự đặc biệt
TT | Biểu thức | Mô tả | Ghi chú |
---|---|---|---|
14 | . | Khớp với bất kỳ ký tự đơn nào ngoại trừ \ | |
15 | ^ |
Bắt đầu của từ Xác định vị trí bắt đầu của dòng, demo |
|
16 | $ |
Kết thúc của từ Xác định vị trí kết thúc của dòng, demo |
|
17 | / | Bắt đầu hoặc kết thúc chuỗi regex | |
18 | | | Sủ dụng tương đương phép or | Hay dùng trong cặp ngoặc tròn |
19 | \ | Biểu diễn một kí tự ngay sau nó từ kí tự đặc biệt thành kí tự thường và ngược lại | VD: \b sẽ trở thành như mình nói ở trên, * sẽ trở thành kí tự * chứ không phải số lần lặp nữa |
20 | \b | Xác định ranh giới của từ, xem demo | |
\B | Phủ định của \b, xem demo |
Giống như ngôn ngữ lập trình có các từ khóa mà bạn không được phép khai báo trùng. Thì regex cũng vậy, nó có các ký tự đặc biệt đang nắm giữ các vai trò quan trọng. Bạn muốn dùng nó thì phải báo cho nó biết:
Cụ thể, các ký tự {}[]()^$.|*+?\
và dấu -
ở trong cặp ngoặc vuông là các ký tự đặc biệt. Nếu bạn muốn dùng nó để so khớp thì cần thêm dấu \
vào đằng trước:
Ví dụ: \.
sẽ khớp với dấu chấm (.) và \\
sẽ khớp với ký tự \
.
1.3 Lặp
STT | Biểu thức | Mô tả | Ghi chú |
---|---|---|---|
20 | * | Xuất hiện 0 hoặc nhiều lần |
viết ngắn gọn cho {0,} |
21 | + | Xuất hiện 1 hoặc nhiều lần |
viết ngắn gọn cho {1,} |
22 | ? | Xuất hiện 0 hoặc 1 lần |
viết ngắn gọn cho {0,1} |
23 | {X} | Xuất hiện X lần |
X không phải số âm |
24 | {X,} | So khớp lặp lại m hoặc nhiều hơn m lần | |
25 | {X,Y} | Xuất hiện trong khoảng X tới Y lần |
X,Y không phải số âm |
26 | ? | có nghĩa là xuất hiện 0 hoặc nhiều lần, thêm ? phía sau nghĩa là tìm kiếm khớp nhỏ nhất |
1.4 Khớp nhóm
STT | Biểu thức | Mô tả | Ghi chú |
---|---|---|---|
26 | () | Khớp với một nhóm các kí tự đồng thời nhớ kết quả khớp | Ví dụ (e|g)mail sẽ khớp với email hoặc gmail. /(ab) (cd) \1 \2/ sẽ khớp với “ab cd ab cd” |
27 | (?:x) | Khớp với x nhưng không nhớ kết quả khớp | “foo foo” sẽ khớp với /(foo) \1/ chứ không khớp với (?:foo) \1 |
28 | x(?=y) | Chỉ khớp x nếu ngay sau x là y | “hello” sẽ khớp với /h(?=e)/ nhưng kết quả trả về chỉ có h |
29 | x(?!y) | Chỉ khớp x nếu ngay sau x không phải là y |
1.5 Một lượt các quy tắc
[xyz]
Tìm và so sánh tất cả ký tự nằm trong dấu ngoặc vuông và trùng khớp với 1 ký tự trong dấu ngoặc vuông. Ví dụ:[31]
sẽ trùng khớp với 3 hoặc 1,[0123456789]
sẽ trùng khớp với bất kỳ một ký tự nào trong khoảng từ 0 đến 9.[a-z]
So sánh và trùng khớp vớimột
ký tự nằm trong khoảng chỉ định. Ví dụ:[a-z]
sẽ trùng khớp với một ký tự trong khoảng từ a đến z nằm trong chuỗi cần test.[0-9]
sẽ trùng khớp với bất kỳ một ký tự nào trong khoảng từ 0 đến 9.[^xyz]
So sánh và không trùng khớp với những ký tự nằm trong khoảng chỉ định. Dấu^
(dấu mũ) nằm trong dấu ngoặc vuông là một dấu phủ định. Ví dụ:[^a-z]
sẽ không trùng khớp với tất cả các ký tự nằm trong khoảng từ a đến z.^
Trùng khớp với phần đầu của chuỗi đích. Ví dụ:^a
sẽ trùng khớp với chữ a trong chuỗi abc,^\w+
sẽ trùng khớp với chữ đầu tiên – chữ “the” của chuỗi “The quick brown fox jumps over the lazy dog”.$
Trùng khớp với phần cuối của chuỗi đích. Ví dụ:c$
sẽ trùng khớp với chữ c trong chuỗi abc,\w+$
sẽ trùng khớp với chữ cuối – chữ “dog” của chuỗi “The quick brown fox jumps over the lazy dog”.+
Trùng khớp với 1 hoặc nhiều lần ký tự đứng trước nó. Ví dụ\d+
sẽ chỉ trùng với chuỗi có từ 1 con số trở lên.*
Trùng khớp với 0 hoặc nhiều lần ký tự đứng trước nó. Ví dụ\d*
sẽ trùng với chuỗi có chứa 1 chữ số hoặc k có chữ số nào cũng đc.?
Trùng khớp với 0 hoặc 1 lần ký tự đứng trước nó. Tương tự như*
nhưng nó lại chỉ nhân lên 1 lần.*
thì nhân lên nhiều lần..
Trùng khớp với 1 ký tự đơn bất kỳ ngoại trừ ký tự ngắt dòng (line-break) và cũng không lấy được ký tự có dấu (unicode). Ví dụ:.
sẽ trùng khớp với ký tự a hoặc b hoặc c trong chuỗi abc. Nhưng.
sẽ không bắt được các chữă
hoặcê
.x{n}
Trùng khớp đúng với n lần ký tự đứng trước nó. n là một số không âm. Ví dụ\d{2}
sẽ bắt đc các số có 2 chữ số đứng liền nhau.x{n,}
Trùng khớp với ít nhất n lần ký tự đứng trước nó. n là một số không âm.Ví dụ\d{2,}
sẽ bắt đc các số có từ 2 chữ số trở lên đứng liền nhau.x{n,m}
Trùng khớp với ít nhất n lần và nhiều nhất là m lần ký tự đứng trước nó. n và m là một số không âm và n <= m. Ví dụ:a{1,3}
sẽ khớp với hah, haah, haaah nhưng không khớp với haaaah.x|y
Trùng khớp với x hoặc y. Ví dụ:slow|fast
sẽ khớp với chữ slow hoặc fast trong chuỗi đích.\b
Trùng khớp với toàn bộ ký tự đứng trước nó. Ví dụ:hello\b
sẽ trùng khớp với toàn bộ từ hello trong chuỗi hello world nhưng sẽ không khớp với chuỗi helloworld.\B
Ngược lại với\b
,\B
sẽ không khớp với toàn bộ mà chỉ 1 phần ký tự đứng trước nó. Ví dụ:hello\B
sẽ trùng khớp với chữ hello trong chuỗi helloworld nhưng sẽ không khớp với chuỗi hello world.\d
Trùng khớp 1 ký tự số (digit).\D
Trùng khớp 1ký tự không phải số (non-digit).\s
Trùng khớp 1 ký tự khoảng trắng (whitespace) bao gồm khoảng trắng tạo ra bởi phím Tab.\S
Trùng khớp với 1 ký tự không phải là khoảng trắng (non-whitespace).\w
Trùng khớp với các ký tự là từ (word) bao gồm dấu_
(underscore) và chữ số.\W
Trùng khớp với các ký tự không phải là từ (non-word). Ví dụ:\W
sẽ khớp với ký tự%
trong chuỗi “100%”.\uxxxx
Trùng khớp với 1 ký tự unicode. Ví dụ:\u00FA
sẽ khớp với ký tự “ú”,\u00F9
sẽ khớp với ký tự “ù”.\pL
Trùng khớp vớimột ký tự
Unicode bất kỳ ngoại trừ dấu cách. Đây chính là cú pháp viết hoàn hảo hơn của dấu.
,Ví dụ\pL+
sẽ lấy được chuỗitruyền
,thuyết
trong chuỗi “truyền thuyết”.
Tham khảo:
Regex là gì? Bạn đã biết sự lợi hại của Regex?
Học Regular Expression và cuộc đời bạn sẽ bớt khổ (Updated v2.2)