Chuyển đến nội dung chính
Mô-đun 2 · Bài học 4 trong tổng số 48/32 trong khóa học~12 min
Bài học theo mô-đun (4/4)

Quay lại: tổng quan

Khi bộ định lượng tham lam "vượt quá", động cơ sẽ thực hiện quay lại: nó lùi lại, thử cấu hình khác, thử lại. Trên các mẫu đơn giản, nó là vô hình; trên các mẫu viết kém, nó có thể trở thành số mũ và đóng băng trình duyệt trong vài giây. Nó là gốc của ReDoS (Thường xuyên biểu thức Từ chối dịch vụ).

Code
Pattern: .*\d
Sample:  abc123def
Steps:
  1.  .*  consumes everything: "abc123def"
  2.  \d  fails (end of string).
  3.  Backtrack: .* drops 'f' -> "abc123de", \d fails on 'f'.
  4.  Backtrack: .* drops 'ef' -> "abc123d", \d fails on 'e'.
  5.  ... and so on until \d finds a digit: match = "abc123" + "?"... actually
       the pattern matches "abc123" because .* leaves "def" and \d looks at '3'? No: the
       backtrack continues and .* ends up being "abc12", \d=3.  Final match: "abc123".

Động cơ luôn ở đó, nhưng nếu bộ định lượng tham lam chứa khác bộ định lượng tham lam (ví dụ: (a+)+), số lượng cấu hình để thử có thể phát nổ.

Mô hình thảm họa

Code
Pattern: (a+)+b
Sample:  aaaaaaaaaaaaaaaaaaaaa

Không có dấu vết b → mẫu không thành công, nhưng để đạt được điều đó, động cơ sẽ thử mọi cách phân vùng có thể có của as. Tăng trưởng theo cấp số nhân: với 30 a giây bạn có thể đợi hàng giờ.

Nguy cơ quay lui và ReDoS

Khi một mẫu chứa các bộ định lượng chồng chéo hoặc lồng nhau (ví dụ: (a+)+), công cụ sẽ đánh giá số lượng đường dẫn theo cấp số nhân trước khi thất bại. Việc thay thế các ký tự đại diện chung bằng việc loại trừ các lớp ký tự sẽ làm giảm đáng kể các đường dẫn quay lui.

Hãy thử nó

tập thể dục#regex.m2.l4.e1
Nỗ lực: 0Đang tải…

Trích xuất nội dung giữa các dấu ngoặc vuông cho mỗi lần xuất hiện trong văn bản. Sử dụng phiên bản lười biếng của bộ định lượng để tránh chuyển sang phần đóng sau này.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

\\[.*?\\] dừng ở lần đóng đầu tiên ]: không quay lại nhiều.

Giải pháp khả dụng sau 3 lần thử

Xem lại bài tập

tập thể dục#regex.m2.l4.e2
Nỗ lực: 0Đang tải…

Tìm mọi URL `http://...` hoặc `https://...` trong văn bản, sử dụng bộ định lượng `?` cho `s` và `\\S+` tùy chọn cho các ký tự không phải khoảng trắng của đường dẫn.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

https? có nghĩa là 'http', theo sau là 's' tùy chọn. Sau đó //, rồi \\S+ (không có dấu cách).

Giải pháp khả dụng sau 3 lần thử

Thử thách bổ sung

tập thể dục#regex.m2.l4.e3
Nỗ lực: 0Đang tải…

Match strings enclosed in double quotes, avoiding excessive backtracking by using the negated class `[^"]*` instead of `.*`.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

Replace the dot with the negated class [^"] to restrict the engine's backtracking paths.

Giải pháp khả dụng sau 3 lần thử