Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Reluctant Quantifiers (Quantifiers ที่ไม่โลภ) ใน Java Regex

Greedy Quantifiers** (ค่าเริ่มต้น) จับคู่มากที่สุดเท่าที่จะเป็นไปได้ (longest match) ถ้าจับคู่ไม่สำเร็จ จะย้อนกลับ (backtrack) ทีละตัว

Reluctant (Non-greedy) Quantifiers** จับคู่น้อยที่สุดเท่าที่จะเป็นไปได้ เริ่มจากตัวแรก ถ้าจับคู่ไม่สำเร็จ จะเพิ่มตัวอักษรทีละตัว

เพิ่ม ? หลัง greedy quantifier จะกลายเป็น reluctant:

Quantifierความหมาย
re*?0 หรือมากกว่า (reluctant)
re??0 หรือ 1 (reluctant)
re+?1 หรือมากกว่า (reluctant)
re{n}?n ครั้งพอดี (reluctant)
re{n,}?อย่างน้อย n (reluctant)
re{n,m}?n ถึง m ครั้ง (reluctant)

ตัวอย่าง: [0-9]+? (Reluctant)

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("Enter input text: ");
        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.print(matcher.group());
            System.out.println();
        }
    }
}

ผลลัพธ์

Enter input text: 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

อธิบาย

  • Input: "12345678" (8 หลัก)
  • Regex [0-9]+? = reluctant: จับคู่ 1 หลัก แล้วหยุด (เพราะ +? = อย่างน้อย 1)
  • หาเจอ 8 ครั้ง แต่ละครั้ง 1 หลัก
  • Greedy [0-9]+ จะจับคู่ "12345678" ครั้งเดียว (ทั้งสตริง)

เปรียบเทียบ

RegexInputจับคู่ได้
[0-9]+ (greedy)1234567812345678 (1 ครั้ง)
[0-9]+? (reluctant)123456781,2,3,4,5,6,7,8 (8 ครั้ง)
[0-9]*? (reluctant)123"", "", "", "" (4 ครั้ง - สตริงว่าง)

เมื่อไหร่ควรใช้ Reluctant?

  • ต้องการจับคู่สั้นที่สุด เช่น <.*?> จับคู่แท็ก HTML เดียว
  • หลีกเลี่ยง over-matching ในกรณีซับซ้อน