Nếu là coder chắc hẵn đa số đều biết qua regex (viết tắt của Regular Expression, tên thuần Việt là biểu thức chính quy). Nó thường được sử dụng để validate chuỗi ký tự như email, ip address hay tìm kiếm/thay thế chuỗi... Regex khá hữu ích không chỉ trong code mà còn cách lĩnh vực khác. Trong bài viết này mình sẽ tổng hợp lại cách dùng cũng như những kinh nghiệm cá nhân trong khi sử dụng regex.
1. Giới thiệu
Trước khi đi vào chi tiết thì mình sẽ nhắc lại regex là gì?
Regular expression viết tắt là regex, regexp, regxp.
Tiếng việt gọi là biểu thức chính quy.
Regular expression là một chuỗi ký tự để định nghĩa một search pattern.
Bản chất thì search pattern là cách biểu diễn cho regular language (là một formal language). Có một cách biểu diễn cho regular language khác mà chắc là một số anh em đã học trong chương trình đại học đó là otomat hữu hạn (finite automaton) trong môn học Chương trình dịch. Có anh em nào còn nhớ cái này không?
Vì regex bản chất là tìm và thay thế chuỗi ký tự nên nó thường được tích hợp trong các ide hay các trình soạn thảo văn bản. Ngoài dân coder, dân văn phòng, viết sách, ... nếu biết cách sài regex cũng rất hữu ích cho công việc. Ví dụ như các xóa khoảng trắng thừa, thêm khoảng trắng vào sau các dấu câu, ...
2. Cú pháp
Hiện tại cách sử dụng regex ở shell linux, các ngôn ngữ lập trình hoặc các ứng dụng soạn thảo văn bản có cú pháp không hoàn toàn giống nhau. Nhưng bản chất đều dựa trên regular language.
Cú pháp ở trong shell linux ví như lệnh grep là theo chuẩn POSIX. Trong chuẩn POSIX thì nó bao gồm 3 kiểu cú pháp cho regex là: BRE (Basic Regular Expressions), ERE (Extended Regular Expressions), và SRE (Simple Regular Expressions). SRE đã bị deprecated và không còn được sử dụng.
Còn các ngôn ngữ lập trình như Java, Javascript, C#, ... sử dụng cú pháp regex tương tự như Perl/PCRE nên cú pháp regex giữa các ngôn ngữ lập trình gần như hoàn toàn giống nhau.
Mình sẽ không nói rõ sự khác nhau giữa cú pháp POSIX hay Perl. Trong bài viết này chỉ tập trung vào cú pháp được sử dụng cho Javascript. Những ngôn ngữ khác có thể khác một chút.
Character classes
Ký tự | Mô tả | Ví dụ |
---|---|---|
. | Match với bất kỳ kí tự trừ ký tự xuống dòng. Để match với tất cả dùng [\s\S] |
|
[] |
Match với ký tự trong[] Có thể dùng - để chỉ phạm vi ký tự |
[a-zA-Z_] match với những ký tự a->z , A->Z và _ |
[^] |
Match với ký tự chứa không chứa trong [^] |
[^a-zA-Z_] match với những ký tự không phải là a->z , A->Z và _ |
\w |
Match với ký tự chữ, số và _ Tương đương với [A-Za-z0-9_] |
|
\W |
Ngược lại với \w |
|
\s |
Match với các loại ký tự khoảng trắng Tương đương với [ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] |
|
\S |
Ngược lại với \s |
|
\d |
Match với số Tương đương với [0-9] |
|
\D |
Ngược lại với \d |
Anchors
Ký tự | Mô tả |
---|---|
^ |
Match với đầu chuỗi |
$ |
Match với cuối chuỗi |
\b |
Match với word boundary |
\B |
Ngược lại với \b |
Escaped characters
Ký tự | Mô tả |
---|---|
\. |
Dùng để escape các ký tự đặc biệt +*?^$\.[]{}()|/ .Bên trong [] chỉ \-] cần escape |
\000 |
Match ký tự theo mã octal |
\xFF |
Match ký tự theo mã hexa |
\uFFFF , \u{FFFF} |
Match ký tự theo mã hexa cho ký tự unicode |
\t |
Match ký tự tab (code 9) |
\n |
Match ký tự new line (code 10) |
\v |
Match ký tự vertical tab (code 11) |
\f |
Match ký tự form feed (code 12) |
\r |
Match ký tự form feed (code 13) |
\0 |
Match ký tự NULL (code 0) |
Quantifiers and alternation
Ký tự | Mô tả | Ví dụ |
---|---|---|
+ |
Match với pattern phía trước một hoặc nhiều lần | |
? |
Match với pattern phía trước không hoặc một lần Nếu trước ? là *, +, ?, {M,N} thì sẽ làm cho chúng match ít nhất có thể |
|
* |
Match với pattern phía trước không hoặc nhiều lần | |
{M} |
Match với pattern phía trước chính xác m lần | |
{M,} |
Match với pattern phía trước nhiều hơn hoặc bằng m lần | |
{M,N} |
Match với pattern phía từ m đến n lần | |
| |
Giống như toán tử or. Chú ý khi sử dụng cùng () thì nó sẽ là 1 nhóm |
https://regexr.com/5hf3f |
Replace
Ký tự | Mô tả |
---|---|
$& |
Toàn bộ string match |
$1 |
string nhóm 1 |
$` |
string trước toàn bộ match |
$' |
string sau toàn bộ match |
$$ |
Escape $ |
\n , \t |
Ký tự đặc biệt |
Ví dụ: https://regexr.com/5hepe
Group and references
Ký tự | Mô tả | Ví dụ |
---|---|---|
(ABC) |
Nhóm để dùng cho replace hoặc xử lý khác | |
\1 |
Match với nhóm trước đó | https://regexr.com/5hemt |
(?:ABC) |
Không nhóm | https://regexr.com/5henl |
Lookaround
Ký tự | Mô tả | Ví dụ |
---|---|---|
(?=ABC) |
Tiếng anh là Positive lookahead. Match với ký tự phía sau main pattern nhưng không đưa vào kết quả Chú ý là cái này ko phải nhóm |
https://regexr.com/5henu |
(?!ABC) |
Tiếng anh là Negative lookahead. Không match với ký tự phía sau main pattern và không đưa vào kết quả Chú ý là cái này ko phải nhóm |
https://regexr.com/5heo1 |
(?<=ABC) |
Tiếng anh là Positive lookbehind. Match với ký tự phía trước main pattern nhưng không đưa vào kết quả Chú ý là cái này ko phải nhóm |
https://regexr.com/5heod |
(?<!ABC |
Tiếng anh là Negative lookahead. Không match với ký tự trước main pattern và không đưa vào kết quả Chú ý là cái này ko phải nhóm |
https://regexr.com/5heog |
3. Flag trong javascript
Ký tự | Mô tả | Ví dụ |
---|---|---|
i |
Không phân biệt hoa thường | |
g |
Tìm tất cả các match. Nếu ko có g flag thì nó sẽ chỉ trả về match đầu tiên | |
m |
Nếu flag này được bật thì ^ ,$ sẽ match với đầu dòng và cuối dòng. Nếu không thì match với đầu chuỗi và cuối chuỗi. Cái này chỉ khác biệt khi trong chuỗi có ký tự xuống dòng |
|
s |
. match với tất cả ký tự kể cả newline |
4. Replace trong vscode
Với anh em coder nếu có sài vscode thì có thể thử tính năng find/replace bằng regex với những modifiers sau cũng rất hữu ích.
Ký tự | Mô tả | |
---|---|---|
\L |
Viết thường toàn bộ | |
\l |
Viết thường chỉ ký tự đầu tiên | |
\U |
Viết hoa toàn bộ | |
\u |
Viết hoa chỉ ký tự đầu tiên |
5. Kết bài
Trên đây mình đã giới thiệu về cách sử dụng của regex và một số kinh nghiệm của bản thân. Hy vọng nó giúp ích cho các anh em. Anh em nào biết rồi hoặc có gì hay thì góp ý, anh em nào còn mù mờ thì có thể xoá bớt sương mù. Thân chào anh em!!!