Phân tích một số đoạn regex thường gặp và cú pháp regex đặc biệt
Bài đăng này đã không được cập nhật trong 3 năm
1. Giới thiệu
Regex (Regular Expression - Biểu thức chính quy) là một chuỗi ký tự đặc biệt được dùng làm mẫu (patern) để phân tích sự trùng khớp của một tập hợp chuỗi nào đó
Được sử dụng trong nhiều ngôn ngữ lập trình như PHP, C#, Perl, Ruby, Javascript ... để kiểm tra tính hợp lệ của các dữ liệu đầu vào, Ví dụ: Kiểm tra email có hợp lệ hay không khi đăng kí người dùng ...
Tình cờ, khi đang tìm kiếm một số đoạn regex để phục vụ cho task thì mình gặp bài viết tổng hợp 30 regex code thường gặp: https://kipalog.com/posts/30-doan-bieu-thuc-chinh-quy-ma-lap-trinh-vien-web-nen-biet Bài viết rất hay, nhưng với một người mới tìm hiểu về regex thì ấn tượng đầu tiên của mình là khá choáng với những đoạn regex dài loằng ngoằng này )
Bởi vậy, bài viết này mình sẽ phân tích một số đoạn regex ở trên, giải thích nó, và dùng rubular.com để lấy một đoạn ví dụ hợp lệ (giáo cụ trực quan )
2. Password Strength và Kí tự "?=" trong regex
Ở bài viết có đoạn regex về password strength như sau
^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$
Nhiệm vụ của chúng ta là phân tích đoạn mã này và từ đó giải thích xem "?=" có tác dụng như thế nào. Ok, đoạn code đã có rồi, vậy câu hỏi là bạn hãy tìm 1 ví dụ hợp lệ với đoạn regex trên Đáp án:
AA@99sds
Vấn đề ở đây là làm cách nào để chúng ta có thể tìm ra được 1 string hợp lệ như vậy: Nhìn vào ví dụ thì các bạn sẽ thấy là: đoạn regex trên sẽ kiểm tra:
- String có chứa 2 chữ hoa hay không?
- Có chứa kí tự đặc biệt hay không?
- Có chứa 2 kí tự số và chữ thường hày không?
- Cuối cùng là string có đủ 8 kí tự hay không?
Đối với regex cơ bản thì giải thích cho chuỗi ở trên sẽ là:
kí tự bất kì
.
Số lần lặp bất kì
*
Chứa 1 kí tự hoa
[A-Z]
Chứa kí tự đặc biệt
[!@#$&*]
Chứa 1 số
[0-9]
Chứa kí tự chữ thường
[a-z]
Chuỗi có it nhất 8 kí tự
{8}
Nếu chỉ với những kiến thức này, chúng ta hoàn toàn có thể tìm ra một chuỗi hợp lệ, nhưng điều này vẫn là chưa hoàn toàn trọn vẹn vì:
Kí tự này có nghĩa là gì
?=
Để giải thích điều này chúng ta có ví dụ sau
Giải thích:
- (?=.u) sẽ tìm trong chuỗi những đoạn có u đứng đằng sau gồm "zu", "ku", "zu"
- Sau đó, từ những đoạn hợp lệ này, sẽ match để tìm ra có kí tự "z" hay không? Và được kết quả như trên, có thể hiểu (?=) như 1 câu if để kiểm tra string có chứa những đoạn mà kí tự đứng trong ở sau hay không? nếu có thì sẽ tiếp tục match với những điều kiện tiếp theo.
3. Kí tự "?!" trong regex
Nhìn có vẻ lạ, nhưng thật ra nó ngược so với "?=" ví dụ
(?!.u)z
thử string "dhzshshuddszuk" thì kết quả trả về sẽ là "z" trong (zsh) giải thích: regex tìm kiếm những đoạn kí tự mà không có chữ u đứng sau (loại bỏ "zu") sau đó thì match "z"
4. Kí tự "?:" trong regex
?: để thông báo rằng đây không là 1 group (None-capturing group) điều này giải thích thế nào:
Khi (24) là 1 group thì \1 sẽ cho phép lặp lại group và nhận được matching như trên hình, Nhưng khi sử dụng
(?:24)5
thì kết quả là matching với "245", nhưng lúc này 24 không là group bởi vậy khi thực hiện
(?:24)5\1
thì sẽ cho kết quả lỗi
5. Kết Luận
Không ai có thể phủ nhận mức độ mạnh của regex trong lập trình, chỉ với ví dụ PASSWORD STRENGTH, check validation với 1 dòng code, nhưng nếu không dùng regex thì bạn có tưởng tượng mình sẽ phải code bao nhiêu dòng if không? Tiết kiệm thời gian, tăng tốc độ chạy chương trình, code gọn và không quá khó hiểu là những ưu điểm chúng ta thấy ở regex. Tìm hiểu nó bạn sẽ thấy nó lợi hại đến mức nào.
6. Tài liệu tham khảo
https://kipalog.com/posts/30-doan-bieu-thuc-chinh-quy-ma-lap-trinh-vien-web-nen-biet http://www.hongkiat.com/blog/regex-web-developers/ http://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group-what-does-a-question-mark-followed-by-a-colon
All rights reserved