Regular Expression คือลำดับตัวอักษรพิเศษกำหนด Pattern ใช้ค้นหา แก้ไข จัดการข้อความ Java มี java.util.regex package
Matcher Class
Matcher เป็น Engine ที่ตีความ Pattern และทำ Match Operations กับ Input String
- ไม่มี public constructors
- สร้างผ่าน
Pattern.matcher(CharSequence)
⚠️ สำคัญ: Instances ของ Matcher Class ไม่ Thread-Safe
ไม่ควรใช้ Matcher instance เดียวกันจากหลาย Thread พร้อมกัน
ไม่ควรใช้ Matcher instance เดียวกันจากหลาย Thread พร้อมกัน
ตัวอย่าง: หาสตริงที่ขึ้นต้นด้วยตัวเลข
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StartingWithDigit {
public static void main(String args[]) {
String regex = "^[0-9].*$"; // เริ่มต้นด้วยตัวเลข
Scanner sc = new Scanner(System.in);
System.out.println("Enter 5 input strings: ");
String[] input = new String[5];
for (int i = 0; i < 5; i++) {
input[i] = sc.nextLine();
}
Pattern p = Pattern.compile(regex);
System.out.println("Strings starting with digits: ");
for (int i = 0; i < 5; i++) {
// สร้าง Matcher ใหม่ทุกครั้ง (Thread-safe way)
Matcher m = p.matcher(input[i]);
if (m.matches()) {
System.out.println(m.group());
}
}
}
}
Output
Enter 5 input strings: sample string 1 sample string 2 11 sample string 3 22 sample string 4 43534 56353 636 Strings starting with digits: 11 sample string 3 22 sample string 4 43534 56353 636
Thread-Safety Summary
| Class | Thread-Safe | หมายเหตุ |
|---|---|---|
| Pattern | ✅ ใช่ | Immutable หลัง compile แล้ว ใช้ร่วมได้ |
| Matcher | ❌ ไม่ | Mutable state (position, groups) - สร้างใหม่ทุก thread |
Best Practice สำหรับ Multi-threaded
// ✅ ดี - Pattern shared, Matcher per-thread
public class RegexUtil {
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[\\w.+-]+@[\\w-]+\\.[\\w.-]+$");
public static boolean isValidEmail(String email) {
// สร้าง Matcher ใหม่ทุกครั้ง
return EMAIL_PATTERN.matcher(email).matches();
}
}
// หรือใช้ ThreadLocal (หากต้อง reuse Matcher - นادرة)
public class ThreadLocalMatcher {
private static final Pattern PATTERN = Pattern.compile("...");
private static final ThreadLocal MATCHER = ThreadLocal.withInitial(() -> PATTERN.matcher(""));
public static boolean matches(String input) {
Matcher m = MATCHER.get();
m.reset(input); // reset ด้วย input ใหม่
return m.matches();
}
}