« Kiểm thử biểu thức chính quy » nghĩa là gì ?
Kiểm thử biểu thức chính quy (« regex test online », « tester regex javascript ») nghĩa là chạy một mẫu trên một văn bản thật và quan sát đúng những gì bộ máy trả về : các chuỗi khớp, vị trí của chúng, và giá trị của các nhóm bắt. Một mẫu « có vẻ đúng » không nói lên gì cho đến khi nó chạy trên dữ liệu của bạn — đó chính là khoảng cách duy nhất đáng kể giữa regex trong tutorial và regex thực tế.
Việc kiểm thử trả lời ba câu hỏi khác nhau. Nó có khớp không : bảng kết quả khớp cho biết ngay dòng đầu tiên. Ở đâu và bao nhiêu : chỉ số và độ dài cho thấy neo có ở đúng chỗ hay không. Nó bắt được gì : các nhóm đánh số hoặc có tên cho thấy phần bạn định trích xuất có đúng là phần đó hay không.
Những siêu ký tự tạo nên khác biệt
Dấu chấm . thay thế bất kỳ ký tự nào trừ dòng mới — nên mới có cờ s khi văn bản của bạn nhiều dòng. Các lượng từ *, + và ? là tham lam : chúng dừng ngay khi số lần lặp là đủ. Hậu tố ? (*?, +?, {2,5}?) đảo ngược hành vi này và cho ra phiên bản lười biếng, phiên bản gần như luôn nên ưu tiên khi một .* nuốt mất cuối dòng.
Ngoặc vuông định nghĩa một lớp : [abc] chấp nhận một ký tự trong số các ký tự được liệt kê, [^abc] mọi thứ trừ chúng, [a-z0-9] một dải. Lưu ý phép phủ định ở đầu lớp — [^...] chỉ dành cho vị trí đầu tiên, nếu không ^ lại thành ký tự thường. Dấu ống | tách các nhánh thay thế và có độ ưu tiên thấp : ^cat|dog$ nghĩa là « toàn bộ văn bản là cat » hoặc « toàn bộ văn bản là dog », không phải « cat hoặc dog ở đầu hay ở cuối » — khi đó phải nhóm lại : ^(?:cat|dog)$.
Nhóm, lookahead và lookbehind
Ngoặc tròn có chức năng bắt. Nhóm 1 truy cập bằng $1 ở phía thay thế và \1 ở phía mẫu, các nhóm có tên với $<nom> và \k<nom> — dễ đọc hơn hẳn khi có từ ba nhóm. (?:...) gộp lại mà không tạo số thứ tự, nên ưu tiên dùng khi bạn chỉ bắt để giữ cấu trúc.
Các dự đoán (lookaround) kiểm tra mà không tiêu thụ : (?=...) yêu cầu phần theo sau phải khớp, (?!...) cấm điều đó, (?<=...) và (?<!...) làm điều tương tự với phần đứng trước. Nhờ vậy mà ta buộc một ký tự đặc biệt phải có trong mật khẩu mà không đưa nó vào nhóm bắt : ^(?=.*\d)(?=.*[A-Z]).{12,}$.
ReDoS : khi regex trở thành quả bom hẹn giờ
Khái niệm ReDoS (Regular Expression Denial of Service) xuất phát từ cơ chế backtracking : trước một đầu vào gần như hợp lệ, một mẫu như (a+)+$ sẽ thử mọi cách để cắt các chữ « a » trước khi thất bại, và số lần bùng nổ tăng theo cấp số nhân. Hai thói quen : kiểm thử mẫu trên một dung lượng thực tế — thẻ Hiệu năng làm việc đó cho bạn — và không bao giờ chạy một regex không kiểm chứng được trên đầu vào từ bên ngoài mà không giới hạn kích thước. Trên máy chủ, một regex bị treo đóng băng toàn bộ worker cho đến khi timeout kết thúc.
JavaScript, PCRE, Python : cùng nền tảng, vài khác biệt
Trình kiểm thử dùng bộ máy mặc định của trình duyệt, tức là ECMAScript. Các cú pháp cơ bản — lớp, lượng từ, nhóm, lookahead, cờ g i m s u y — dùng chung cho PCRE (PHP, Perl), cho Python với re, cho Java và Go. Các khác biệt chủ yếu nằm ở lookbehind (trước đây JavaScript không có, nay đã hỗ trợ), ở các thuộc tính Unicode và ở các cờ nội tuyến như (?i), chỉ có ở PCRE. Vì vậy chuyển một mẫu từ ngôn ngữ này sang ngôn ngữ khác vẫn là việc tỉ mỉ — không phải sáng tạo.
Khuyến nghị cho
Nhà phát triển front-end và back-end (kiểm tra biểu mẫu, đọc log, di chuyển dữ liệu), ops và DevOps (lọc cấu hình, quy tắc WAF), tester và chuyên viên phân tích (trích cột, kiểm định dạng), biên tập viên và chuyên viên phân tích dữ liệu (dọn tệp), sinh viên (hiểu siêu ký tự), và bất kỳ ai cần một trình kiểm thử biểu thức chính quy nhanh, đầy đủ và bảo mật — kèm theo trình định dạng JSON, công cụ mã hóa và giải mã URL, công cụ mã hóa và giải mã Base64 và công cụ mã hóa và giải mã JWT.