Quantifiers ใช้ระบุจำนวนครั้งของการเกิดซ้ำของ pattern ใน Regular Expression Java รองรับ 3 ประเภทหลัก:
1. Greedy Quantifiers (ขี้หิ้ว - เริ่มต้นค่าเริ่มต้น)
Match มากที่สุดเท่าที่จะเป็นไปได้ (longest match) หาก match ไม่สำเร็จ จะ backtrack (ย้อนกลับ) ตัวอักษรทีละตัวจนกว่าจะ match ได้
| Quantifier | ความหมาย |
|---|---|
X? |
X เกิด 0 หรือ 1 ครั้ง |
X* |
X เกิด 0 ครั้งขึ้นไป |
X+ |
X เกิด 1 ครั้งขึ้นไป |
X{n} |
X เกิด n ครั้งพอดี |
X{n,} |
X เกิด n ครั้งขึ้นไป |
X{n,m} |
X เกิด n ถึง m ครั้ง |
ตัวอย่าง Greedy: [0-9]+
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);
System.out.println("Matched text:");
while (matcher.find()) {
System.out.println(matcher.group());
}
}
}
Output
Enter input text: abc123def456 Matched text: 123 456
2. Reluctant (Non-greedy) Quantifiers (ไม่ขี้หิ้ว)
Match น้อยที่สุดเท่าที่จะเป็นไปได้ (shortest match) เริ่มจาก match ตัวเดียว แล้วค่อยเพิ่มทีละตัวจนกว่าจะ match ได้ ใช้โดยใส่ ? หลัง greedy quantifier
| Quantifier | ความหมาย |
|---|---|
X?? |
X เกิด 0 หรือ 1 ครั้ง (reluctant) |
X*? |
X เกิด 0 ครั้งขึ้นไป (reluctant) |
X+? |
X เกิด 1 ครั้งขึ้นไป (reluctant) |
X{n,}? |
X เกิด n ครั้งขึ้นไป (reluctant) |
X{n,m}? |
X เกิด n ถึง m ครั้ง (reluctant) |
ตัวอย่าง Reluctant: [0-9]+?
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.println(matcher.group());
}
}
}
Output
Enter input text: 12345678 1 2 3 4 5 6 7 8
คำอธิบาย: +? match ตัวเลขทีละตัว เพราะพยายาม match น้อยที่สุด
3. Possessive Quantifiers (ครอบครอง - ไม่ย้อนกลับ)
คล้าย Greedy (match มากที่สุด) แต่ ไม่ backtrack เลย หาก match ไม่สำเร็จ จะ fail ทันที ใช้โดยใส่ + หลัง greedy quantifier
| Quantifier | ความหมาย |
|---|---|
X?+ |
X เกิด 0 หรือ 1 ครั้ง (possessive) |
X*+ |
X เกิด 0 ครั้งขึ้นไป (possessive) |
X++ |
X เกิด 1 ครั้งขึ้นไป (possessive) |
X{n,}+ |
X เกิด n ครั้งขึ้นไป (possessive) |
X{n,m}+ |
X เกิด n ถึง m ครั้ง (possessive) |
ตัวอย่าง Possessive: [0-9]++
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.println(matcher.group());
}
}
}
Output
Enter input text: 45678 45678
ตารางเปรียบเทียบพฤติกรรม
| Input | Regex | Match Result | ประเภท |
|---|---|---|---|
"abc123" |
[a-z]+ |
"abc" |
Greedy |
"abc123" |
[a-z]+? |
"a" |
Reluctant |
"abc123" |
[a-z]++ |
"abc" |
Possessive |
"aaab" |
a+b |
"aaab" (match) |
Greedy + backtrack |
"aaab" |
a++b |
No match (a++ กินหมด aaa แล้วไม่เหลือ b) | Possessive - no backtrack |
เมื่อไหร่ควรใช้แบบไหน?
- Greedy - ใช้ส่วนใหญ่ ค่าเริ่มต้น เหมาะสำหรับการ match แบบปกติ
- Reluctant - เมื่อต้องการ match น้อยที่สุด เช่น parsing HTML tags
<.+?> - Possessive - เพื่อประสิทธิภาพและป้องกัน catastrophic backtracking เมื่อแน่ใจว่า pattern ต่อท้ายไม่ overlap