# Regular Expression
Regular Expression (hay còn gọi là regex) là một công cụ, khuôn mẫu để tìm và xử lí các xâu. Chúng có thể dùng trong việc tìm kiếm, thay thế văn bản hoặc xác thực, lưu trữ các xâu khớp với quy tắc đặt ra từ nhà phát triển.
## I. Basic Matchers
Với basic matchers, chúng ta có thể hiểu đơn giản là biểu thức sẽ match với một xâu khi tồn tại từ đó hoặc cụm từ đó. Ví dụ như "ATTN" trong "ATTN2024" hay "Hell" trong "Hello World".
[Test this regex](https://regex101.com/r/KKaQ7C/1)
## II. Meta Matchers
- Cheatsheet:
| Meta character | Description |
| -------------- | ----------------------------------------------------------------------------------------------------- |
| . | Khớp với tất cả các kí tự trừ dấu xuống dòng. |
| [] | Lớp kí tự. Khớp với bất kỳ ký tự nào nằm giữa dấu ngoặc vuông. |
| [^] | Lớp kí tự phủ định. Khớp với bất kỳ ký tự nào không có trong dấu ngoặc vuông. |
| \* | Khớp 0 hoặc nhiều lần lặp lại của kí tự trước. |
| + | Khớp 1 hoặc nhiều lần lặp lại của kí tự trước. |
| ? | Làm cho kí tự trước tùy chọn. |
| {n,m} | Khớp ít nhất là "n" nhưng không nhiều hơn "m" lặp lại của kí tự trước. |
| (xyz) | Nhóm kí tự. Khớp các ký tự xyz theo thứ tự chính xác đó. |
| \| | Thay thế. Khớp các ký tự trước hoặc ký tự sau ký hiệu. |
| \ | Thoát khỏi kí tự tiếp theo. Điều này cho phép bạn khớp các ký tự dành riêng [ ] ( ) { } . * + ? ^ $ \ |
| ^ | Khớp với sự bắt đầu của đầu vào. |
| $ | Khớp với kết thúc đầu vào. |
### 1. Full Stop /.
Full stop **/.** dùng để match tất cả kí tự , ngoại trừ xuống dòng. [Test Regex](https://regex101.com/r/FDuaZp/1)
### 2. Character set /[]
Charater set /[] là tập kí tự ta có thể dùng được trong xâu. Ta còn có thể sử dụng dấu gạch để chỉ phạm vi của kí tự. Ví dụ như [A-Za-z0-9].
[Test Regex](https://regex101.com/r/SKex0L/1)
[Test Regex](https://regex101.com/r/6UzXIp/1)
#### 2.1 Negated character set /[^]
Ở ký tự ^ đặt trong [] dùng để phủ định các kí tự có trong tập. Khi sử dụng có thể bỏ qua các kí tự đó và khớp các kí tự còn lại của xâu. [Test Regex](https://regex101.com/r/7YFx6l/1)
### 3. Repetitions (Quantifier )
#### 3.1 The Star /*
Khớp với 0 hoặc nhiều kí tự đằng sau. [Test Regex](https://regex101.com/r/xz4Itu/3)
#### 3.2 The Plus /+
Tương tự như * nhưng không khớp với tập rỗng "". [Test Regex](https://regex101.com/r/gfiQwz/2)
#### 3.3 The Question Mark /?
Nếu có kí tự đằng trước dấu **?**, thì sẽ match cả chữ. Nếu không có kí tự đằng trước dấu **?**, thì chỉ match các chữ đằng sau dấu **?**. [Test Regex](https://regex101.com/r/3CUyA0/1)
### 3.4 Braces /{}
Lấy số kí tự lặp lại đằng trước kí hiệu **{}**, và các số ở trong kí hiệu **{}** là min và max.
[Test Regex](https://regex101.com/r/G5ckdh/1) (Có cả min và max)
[Test Regex](https://regex101.com/r/a5ZmKT/1) (Chỉ ghi max)
[Test Regex](https://regex101.com/r/BrXU2n/1) (Chỉ ghi min)
### 4. Alternation /|
Tương tự như mệnh đề or, khớp 1 trong 2 bên của kí hiệu **|**. [Test Regex](https://regex101.com/r/f3CyiR/2)
### 5. Capturing Group /()
Capturing group là sử dụng so khớp trong 1 nhóm phần tử, tuy nhiên sẽ lưu lại thành các group. Có thể trích xuất từ các group 1,2,3,... trong một số ngôn ngữ. [Test Regex](https://regex101.com/r/fTW0QI/1)
#### 5.1 Non-capturing group /(?:)
Khác với **()** bình thường, nó chỉ dùng để nhóm các phần tử lại với nhau mà không tạo group index. Sử dụng non-capturing group sẽ tối ưu hơn khi chỉ muốn nhóm các phần tử lại với nhau mà không cần trích xuất chúng. [Test Regex](https://regex101.com/r/5SjnsF/1)
### 6. Escaping special character
Dùng để sử dụng các kí tự trùng với meta character như (), [], {}, \*, +,| ,^ ,\$ ,\\ ,? [Test Regex](https://regex101.com/r/0bjO40/3)
### 7. Anchors
#### 7.1 Caret
Kiểm tra các kí tự đằng trước dòng. [Test Regex](https://regex101.com/r/Ylk4Ui/1)
#### 7.2 Dollar
Kiểm tra các kí tự ở cuối dòng. [Test Regex](https://regex101.com/r/s02IL1/1)
## III. Shorthand Character Sets
| Shorthand | Description |
| --------- | --------------------------------------------- |
| \w | Khớp các ký tự chữ và số: [a-zA-Z0-9_] |
| \W | Khớp các ký tự không phải chữ và số:[^\w] |
| \d | Khớp với số trong khoảng: [0-9] |
| \D | Khớp không có chữ số: [^\d] |
| \s | Khớp các ký tự khoảng trắng:[\t\n\f\r\p{Z}] |
| \S | Khớp với ký tự không phải khoảng trắng: [^\s] |
## IV. Lookaround
Lookaround là các toán tử dùng để kiểm tra, đặt điều kiện khi so khớp một xâu. Thay vì tìm tất cả các xâu, chúng ta có thể đặt điều kiện rằng xâu đó phải đằng trước kí tự gì,
### 1. Positive lookahead /(?= )
Phần khớp trả về sẽ nằm trước kí tự hoặc từ ở trong **(?= )**. [Test Regex](https://regex101.com/r/KeQBBE/1)
### 2. Negative Lookahead /(?! )
Phần khớp trả về sẽ nằm trước kí tự hoặc từ không ở trong **(?= )**. [Test Regex](https://regex101.com/r/pLm5TN/1)
### 3. Positive Lookbehind
Phần khớp trả về sẽ nằm sau kí tự hoặc từ ở trong **(?= )**. [Test Regex](https://regex101.com/r/pt5Tn0/1)
### 4. Negative Lookbehind
Phần khớp trả về sẽ nằm sau kí tự hoặc từ không ở trong **(?= )**. [Test Regex](https://regex101.com/r/J5MWsC/1)
## V. Flags
| Flags | Description | Test Regex |
| ----- | ------------------------------------------------------------- | --------------------------------------- |
| /i | Không phân biệt chữ hoa, thường | [Link](https://regex101.com/r/juhszf/1) |
| /g | Kiểm tra toàn bộ văn bản, thay vì chỉ tìm được 1 case rồi out | [Link](https://regex101.com/r/IQUXLc/1) |
| /m | Kiểm tra anchors ^ và \$ nhiều dòng | [Link](https://regex101.com/r/t1z3IW/1) |
## VI. Lazy Matching
Nếu **Greedy Matching** là setting mặc định của regex để match càng nhiều càng tốt, thì **Lazy Matching** là cách regex tìm ít nhất có thể. Cách dùng Lazy Matching đó là đặt ? đằng sau quantifier. Ví dụ: .\*?, .+?, {n,m}?
[Test Regex](https://regex101.com/r/bXaSUC/1) (Greedy Matching)
[Test Regex](https://regex101.com/r/rRbHny/1) (Lazy Matching)