Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Các loại Quantifier (lượng từ) trong Java Regex

Khi xây dựng biểu thức chính quy, nếu cần chỉ định số lần xuất hiện của một mẫu, ta sử dụng quantifier (lượng từ). Java hỗ trợ 3 loại quantifier chính:

  • Greedy (Tham lam) - Mặc định
  • Reluctant / Non-greedy (Ngại ngùng / Không tham lam)
  • Possessive (Hưu đãi / Độc chiếm)

1. Greedy Quantifiers (Mặc định)

Khớp nhiều nhất có thể (longest match). Nếu không khớp toàn bộ, nó backtrack (lùi lại) bỏ bớt ký tự cuối và thử lại.

Ký hiệuÝ nghĩa
X?0 hoặc 1 lần
X*0 hoặc nhiều lần
X+1 hoặc nhiều lần
X{n}Đúng n lần
X{n,}Ít nhất n lần
X{n,m}Từ n đến m lần

Ví dụ: [0-9]+ (Greedy)

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);

        System.out.println("Văn bản khớp:");
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

Kết quả

Nhập văn bản: abc123def456
Văn bản khớp:
123
456

2. Reluctant Quantifiers (Non-greedy)

Khớp ít nhất có thể. Ban đầu khớp 1 ký tự, nếu thất bại thì thêm ký tự tiếp theo. Được tạo bằng cách thêm ? sau greedy quantifier.

GreedyReluctant
X*X*?
X+X+?
X?X??
X{n,}X{n,}?
X{n,m}X{n,m}?

Ví dụ: [0-9]+? (Reluctant)

String regex = "[0-9]+?";
// Input: 12345678
// Output: 1 2 3 4 5 6 7 8 (mỗi số 1 dòng)

Kết quả

Nhập văn bản: 12345678
1
2
3
4
5
6
7
8

3. Possessive Quantifiers

Tương tự greedy (khớp nhiều nhất), nhưng KHÔNG backtrack. Nếu khớp thất bại, nó dừng lại ngay, không thử lùi lại. Tạo bằng cách thêm + sau greedy quantifier.

GreedyPossessive
X*X*+
X+X++
X?X?+
X{n,}X{n,}+
X{n,m}X{n,m}+

Ví dụ: [0-9]++ (Possessive)

String regex = "[0-9]++";
// Input: 45678
// Output: 45678 (khớp toàn bộ, không backtrack)

Kết quả

Nhập văn bản: 45678
45678

Bảng so sánh hành vi

Loại Ký hiệu Chiến lược Backtrack? Hiệu năng khi thất bại
GreedyX*, X+Khớp max, rồi lùi dầnCóChậm nếu pattern phức tạp thất bại
ReluctantX*?, X+?Khớp min, rồi mở rộng dầnCóChậm nếu phải mở rộng nhiều lần
PossessiveX*+, X++Khớp max, không lùiKhôngNhanh khi thất bại (fail-fast)

Khi nào dùng loại nào?

  • Greedy: Mặc định, phù hợp đa số trường hợp đơn giản.
  • Reluctant: Khi cần khớp ngắn nhất (ví dụ: khớp thẻ HTML <.+?> thay vì <.+>).
  • Possessive: Tối ưu hiệu năng, tránh catastrophic backtracking trên pattern phức tạp (ví dụ: [0-9]++ thay vì [0-9]+ khi biết chắc chuỗi chỉ toàn số).