Xin chào các bạn, bài viết này mình sẽ giới thiệu với các bạn một vài kiến thức của biểu thức chính quy hay còn gọi regular expression (viết tắt là regex).

Đây là bài viết mình viết ra trong quá trình tìm hiểu về regex, nếu có sai sót gì mong các bạn phản hồi giúp mình.

Biểu thức chính quy là gì

Theo Wiki định nghĩa:

Biểu thức chính quy (tiếng Anh: regular expression, viết tắt là regexp, regex hay regxp) là một chuỗi miêu tả một bộ các chuỗi khác, theo những quy tắc cú pháp nhất định.

Biểu thức chính quy thường được dùng trong các trình biên tập văn bản và các tiện ích tìm kiếm và xử lý văn bản dựa trên các mẫu được quy định.

Các thành phần của biểu thức chính quy

Trước khi vào tìm hiểu thì mình giới thiệu cho các bạn một tool để kiểm tra regex, bạn có thể sử dụng tại đây.

Modifiers (Bổ ngữ)

Trong regex có một vài modifiers phổ biến như sau:

  • /g: (global) nếu không có bổ ngữ g thì regex chỉ khớp với phần tử đầu tiên. Nếu có bổ ngữ g thì nó sẽ khớp với tất cả những phần tử.
  • /i: (case insensitive) bổ ngữ i được sử dụng để bỏ qua hoa thường.
  • /m: (multiline) được sử dụng trên nhiều dòng.

Cùng xem vài ví dụ dưới đây để hiểu hơn.

/abc/

không có mdifier g

Nếu không có bổ ngữ g thì nó chỉ khớp với abc đầu tiên.

/abc/g

có modifier g

Nếu có bổ ngữ g thì nó sẽ khớp với tất cả abc.

/abc/gi

có modifier gi

Nếu có bổ ngữ gi thì nó sẽ khớp với tất cả abc, Abc vì bỏ qua hoa thường.

Lưu ý: gi ở đây là sự kết hợp của cả hai g (global) và i (case insensitive).

Quantifiers (Bộ định lượng)

Dưới đây là một số quantifiers phổ biến:

Quantifier Ý nghĩa
* Lặp lại 0 hoặc nhiều lần
+ Lặp lại ít nhất 1 lần
? Lặp lại 0 hoặc 1 lần
{n} Lặp lại đúng n lần
{n,} Lặp lại ít nhất là n lần, * có thể được xem là viết tắt của {0,}+ có thể được xem là viết tắt của {1,}
{n,m} Lặp lại ít nhất là n lần và tối đa là m lần

Ví dụ:

  • /ba*/g: b, ba, baaa
  • /ba+/g: b, ba, baaa
  • /ba{3}/g: b, ba, baaa

Assertions

Dưới đây là một số assertion phổ biến:

Assertion Ý nghĩa
^ Đánh dấu bắt đầu của một regex
$ Đánh dấu kết thúc của một regex

Ví dụ:

Ta có thể kiểm tra một dòng có bắt đầu bằng kí tự a không?

  • /^a/: abcd
  • /^a/: cabcd

Ta có thể kiểm tra một dòng có kết thúc bằng kí tự d không?

  • /d$/: abcd
  • /d$/: abcde

Groups

  Ý nghĩa
() Dùng để đánh dấu một nhóm
a | b Khớp với a hoặc b
[abc] Khớp với a, b hoặc c. Tương đương [a-c]
[^abc] Khớp với kí tự bất kì khác a, b hoặc c. Tương đương [^a-c]
[a-z] Khớp với một kí tự bất kì trong đoạn a-z
[^a-z] Khớp với một kí tự bất kì mà không nằm trong đoạn a-z

Ví dụ:

Kiểm tra định dạng ngày tháng ta có mẫu ^[0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{4}$ hay có thể viết gọn lại ^\d{1,2}[-/]\d{1,2}[-/]\d{4}$.

Mẫu này có thể khớp với các dữ liệu như:

  • 25/06/1999
  • 25-06-1999
  • 25/06-1999
  • 25/6/1999
  • 2/06/1999

Bạn thấy mẫu 25/06-1999 nó không đồng nhất. Giờ bạn chỉ muốn nhận 25/06/1999 hoặc 25-06-1999 thì bạn sẽ sử dụng mẫu sau ^\d{1,2}([-/])\d{1,2}\1\d{4}$

Bạn sẽ thấy lạ khi có \1. Nó chính là đại diện cho mẫu ([-/]). Nếu ([-/]) khớp với kí tự - thì \1 sẽ đại diện cho kí tự -.

Lưu ý: Group sẽ bắt đầu từ \1 trở đi (\2, …).

Meta characters

Dưới đây là một số meta characters phổ biến:

Meta character Ý nghĩa
. Khớp với kí tự bất kì
\ Dùng để thoát các kí tự đặc biệt. Ví dụ dấu chấm (.) là một kí tự đặc biệt. Để khớp với dấu chấm trong regex thì ta phải dùng thêm dấu \ phía trước dấu chấm
\d Khớp với một số. Tương đương [0-9]
\D Khớp với một kí tự khác số. Tương đương [^0-9]
\n Khớp với kí tự xuống hàng (Unix & Windows)
\r Khớp với kí tự xuống hàng (Macintosh & Windows)
\s Khớp với kí tự khoảng trắng
\S Khớp với kí tự không phải khoảng trắng
\t Khớp với kí tự tab ngang
\v Khớp với kí tự tab dọc
\w Khớp với tất cả kí tự là chữ, số và gạch dưới. Tương đương [0-9a-zA-Z_]
\W Khớp với tất cả kí tự không phải là chữ. Tương đương [^0-9a-zA-Z_]

Kết luận

Như vậy bài viết này chúng ta đã hiểu được regex và cú pháp để viết một regex đơn giản. Để thành thục regex thì không có cách nào khác ngoài việc bạn phải luyện tập nhiều.

Cám ơn các bạn đã theo dõi, chúc các bạn một ngày mới tốt lành!