Khái niệm
Greedy (mặc định): khớp nhiều nhất có thể, backtrack nếu cần.
Reluctant (Non-greedy): khớp ít nhất có thể, mở rộng dần nếu cần. Thêm ? sau quantifier.
Danh sách Reluctant Quantifiers
| Quantifier | Mô tả |
|---|---|
re*? | 0 hoặc nhiều lần (ít nhất) |
re?? | 0 hoặc 1 lần |
re+? | 1 hoặc nhiều lần (ít nhất) |
re{n}? | Chính xác n lần |
re{n,}? | Tối thiểu n lần |
re{n,m}? | Từ n đến m lần (ít nhất) |
Ví dụ: [0-9]+? trên "12345678"
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Nhập văn bản: ");
String input = sc.nextLine();
String regex = "[0-9]+?";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.print("Pattern found from " + matcher.start() + " to " + (matcher.end()-1) + "::");
System.out.println(matcher.group());
}
}
}
Kết quả
Nhập văn bản: 12345678
Pattern found from 0 to 0::1
Pattern found from 1 to 1::2
Pattern found from 2 to 2::3
Pattern found from 3 to 3::4
Pattern found from 4 to 4::5
Pattern found from 5 to 5::6
Pattern found from 6 to 6::7
Pattern found from 7 to 7::8
So sánh Greedy vs Reluctant
| Input | Greedy \d+ | Reluctant \d+? |
|---|---|---|
| 12345 | 1 match: "12345" | 5 matches: "1","2","3","4","5" |
| abc123def | 1 match: "123" | 1 match: "1" (rồi "2", "3") |
Khi nào dùng Reluctant?
- Parse HTML/XML:
<.*?>thay vì<.*>(tránh khớp qua nhiều thẻ) - Tách token tối thiểu
- Tránh catastrophic backtracking