0Pricing
Java Academy · บทเรียน

นิพจน์ทั่วไปด้วย Pattern และ Matcher

ตรวจสอบอีเมล แยกสตริงย่อย และแทนที่รูปแบบโดยใช้นิพจน์ทั่วไปของ Java

นิพจน์ทั่วไปด้วย Pattern และ Matcher เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

นิพจน์ปกติด้วย Pattern และ Matcher

แพ็กเกจ java.util.regex ของ Java มี Pattern และ Matcher สำหรับการจับคู่ข้อความ การตรวจสอบความถูกต้อง การดึงข้อมูล และการแทนที่ที่มีประสิทธิภาพ

เหตุใดจึงใช้นิพจน์ปกติ

นิพจน์ปกติ (regex) คือรูปแบบสำหรับจับคู่ข้อความ ใน Java นิพจน์เหล่านี้ใช้ตรวจสอบอีเมลและหมายเลขโทรศัพท์ ดึงข้อมูลจากบันทึก และแยกวิเคราะห์ข้อความที่มีโครงสร้าง

import java.util.regex.*;

// Is this a valid email?
String email = "alice@example.com";
boolean valid = email.matches("[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}");
System.out.println(valid); // true

// Extract version numbers from a string
String log = "App v1.2.3 deployed; api v2.0.0 started";
Pattern p = Pattern.compile("v(\\d+\\.\\d+\\.\\d+)");
Matcher m = p.matcher(log);
while (m.find()) System.out.println(m.group(1));
// 1.2.3 
// 2.0.0

พื้นฐานไวยากรณ์นิพจน์ปกติ

เมตาอักขระสำคัญของนิพจน์ปกติ:

  • . — อักขระใด ๆ
  • \d — ตัวเลข; \w — อักขระคำ; \s — ช่องว่าง
  • * — 0 ครั้งขึ้นไป; + — 1 ครั้งขึ้นไป; ? — 0 หรือ 1 ครั้ง
  • {n,m} — ระหว่าง n ถึง m ครั้ง
  • ^/$ — จุดเริ่มต้น/จุดสิ้นสุดของบรรทัด
  • [abc] — คลาสอักขระ
// In Java strings, backslash must be doubled: \d = "\\d"
Pattern digit   = Pattern.compile("\\d+");      // one or more digits
Pattern word    = Pattern.compile("\\w{3,20}");  // 3-20 word chars
Pattern space   = Pattern.compile("\\s+");       // whitespace
Pattern phone   = Pattern.compile("\\d{3}-\\d{3}-\\d{4}"); // 555-867-5309

System.out.println(digit.matcher("42").matches());       // true
System.out.println(phone.matcher("555-867-5309").matches()); // true

Pattern.compile และ Matcher

คอมไพล์รูปแบบหนึ่งครั้งแล้วนำ Matcher กลับมาใช้กับอินพุตหลายรายการ วิธีนี้มีประสิทธิภาพมากกว่าการใช้ String.matches() เมื่อต้องตรวจสอบซ้ำ

import java.util.regex.*;

Pattern emailPattern = Pattern.compile(
    "^[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,6}$"
);

String[] emails = {"alice@example.com", "bad@", "test.user@co.uk", "no-at-sign"};
for (String e : emails) {
    Matcher m = emailPattern.matcher(e);
    System.out.println(e + " -> " + (m.matches() ? "valid" : "invalid"));
}

find() เทียบกับ matches()

matches() จะทดสอบ String ทั้งหมด ส่วน find() จะค้นหาการปรากฏครั้งถัดไปภายใน String โปรดใช้ find สำหรับการค้นหา และใช้ matches สำหรับการตรวจสอบ String ทั้งหมด

import java.util.regex.*;

Pattern price = Pattern.compile("\\d+\\.\\d{2}");

String invoice = "Total: 129.99, Tax: 10.40, Shipping: 5.00";
Matcher m = invoice.matcher(invoice);

// find() locates all matches
while (m.find()) {
    System.out.println("Found: " + m.group() + " at " + m.start());
}
// Found: 129.99 at 7
// Found: 10.40 at 20
// Found: 5.00 at 34

กลุ่มการจับคู่

วงเล็บจะสร้างกลุ่มการจับคู่ ใช้ group(n) เพื่อดึงซับสตริงที่จับคู่ได้

import java.util.regex.*;

Pattern date = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher m = date.matcher("Deployed on 2024-06-15 and 2024-07-01");

while (m.find()) {
    String year  = m.group(1);
    String month = m.group(2);
    String day   = m.group(3);
    System.out.println(year + "/" + month + "/" + day);
}
// 2024/06/15
// 2024/07/01

กลุ่มที่มีชื่อ

กลุ่มที่มีชื่อ (?<name>...) ทำให้กลุ่มการจับคู่อ่านเข้าใจง่ายขึ้นและเข้าถึงได้ด้วยชื่อ

import java.util.regex.*;

Pattern log = Pattern.compile(
    "(?<timestamp>\\d{4}-\\d{2}-\\d{2}) (?<level>[A-Z]+) (?<message>.+)"
);

String line = "2024-06-15 ERROR Database connection failed";
Matcher m = log.matcher(line);

if (m.matches()) {
    System.out.println("Time: "    + m.group("timestamp"));
    System.out.println("Level: "   + m.group("level"));
    System.out.println("Message: " + m.group("message"));
}
// Time: 2024-06-15
// Level: ERROR
// Message: Database connection failed

replaceAll และ replaceFirst

การแทนที่ตามรูปแบบ: แทนที่ทุกการปรากฏ หรือแทนที่เฉพาะรายการแรก

import java.util.regex.*;

String text = "Call us at 123-456-7890 or 098-765-4321";

// Mask phone numbers for privacy logs
String masked = text.replaceAll("\\d{3}-\\d{3}-\\d{4}", "XXX-XXX-XXXX");
System.out.println(masked);
// Call us at XXX-XXX-XXXX or XXX-XXX-XXXX

// Replace multiple whitespace with single space
String cleaned = "too   many   spaces".replaceAll("\\s+", " ");
System.out.println(cleaned); // too many spaces

split() กับนิพจน์ปกติ

String.split() ยอมรับนิพจน์ปกติ โปรดใช้เพื่อแยกข้อความด้วยตัวคั่นหลายรูปแบบหรือตัวคั่นที่ซับซ้อน

// Split on comma with optional spaces
String csv = "Alice, Bob,  Charlie,Diana";
String[] names = csv.split("\\s*,\\s*");
for (String name : names) System.out.println("'" + name + "'");
// 'Alice' 'Bob' 'Charlie' 'Diana'

// Split on any whitespace
String words = "one  two\tthree  four";
String[] parts = words.split("\\s+");
System.out.println(parts.length); // 4

// Limit splits
String line = "key=value=extra";
String[] kv = line.split("=", 2); // [key, value=extra]

แฟล็กของรูปแบบ

แฟล็กจะปรับเปลี่ยนพฤติกรรมของนิพจน์ปกติ ได้แก่ การไม่คำนึงถึงตัวพิมพ์เล็กใหญ่, MULTILINE และ DOTALL

import java.util.regex.*;

// Case-insensitive match
Pattern p = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);
System.out.println(p.matcher("HELLO World").find()); // true

// MULTILINE: ^ and $ match line boundaries
Pattern multi = Pattern.compile("^ERROR", Pattern.MULTILINE);
String logs = "INFO start\nERROR crash\nINFO end";
Matcher m = multi.matcher(logs);
int count = 0;
while (m.find()) count++;
System.out.println("ERROR lines: " + count); // 1

การใช้งานจริง: ตัวแยกวิเคราะห์บันทึก

แยกวิเคราะห์บรรทัดบันทึกการเข้าถึงรูปแบบ Apache ด้วยกลุ่มที่มีชื่อ

import java.util.regex.*;

Pattern accessLog = Pattern.compile(
    "(?<ip>[\\d.]+) - - \\[(?<time>[^\\]]+)\\] " +
    "\"(?<method>[A-Z]+) (?<path>[^ ]+)[^\"]*\" " +
    "(?<status>\\d{3}) (?<bytes>\\d+)"
);

String line = "192.168.1.1 - - [27/May/2024:10:30:00 +0000] \"GET /api/products HTTP/1.1\" 200 1024";
Matcher m = accessLog.matcher(line);
if (m.matches()) {
    System.out.println("IP: "     + m.group("ip"));
    System.out.println("Method: " + m.group("method"));
    System.out.println("Status: " + m.group("status"));
}

ตรวจสอบอย่างรวดเร็ว

Matcher มีความแตกต่างระหว่าง matches() และ find() อย่างไร

สรุป: นิพจน์ปกติด้วย Pattern และ Matcher

ประเด็นสำคัญ:

  • Pattern.compile() คอมไพล์นิพจน์ปกติ ส่วน Matcher ใช้ทดสอบกับ String
  • matches() ตรวจสอบ String ทั้งหมด ส่วน find() ค้นหาการปรากฏ
  • กลุ่มการจับคู่ () ใช้ดึงซับสตริง โดยเข้าถึงผ่านหมายเลขหรือชื่อกลุ่ม
  • กลุ่มที่มีชื่อ (?<name>...) ทำให้รูปแบบอ่านเข้าใจง่ายขึ้น
  • replaceAll() และ split() ยอมรับรูปแบบนิพจน์ปกติสำหรับการจัดการข้อความที่ยืดหยุ่น
  • ใช้แฟล็ก Pattern ที่ไม่คำนึงถึงตัวพิมพ์เล็กใหญ่, MULTILINE และ DOTALL เพื่อปรับเปลี่ยนพฤติกรรมการจับคู่

คำถามที่พบบ่อย

บทเรียน “นิพจน์ทั่วไปด้วย Pattern และ Matcher” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “นิพจน์ทั่วไปด้วย Pattern และ Matcher” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “นิพจน์ทั่วไปด้วย Pattern และ Matcher”

ตรวจสอบอีเมล แยกสตริงย่อย และแทนที่รูปแบบโดยใช้นิพจน์ทั่วไปของ Java คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “นิพจน์ทั่วไปด้วย Pattern และ Matcher” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ความไม่เปลี่ยนแปลงของ String และ String Pool
  2. StringBuilder สำหรับการต่อสตริงอย่างมีประสิทธิภาพ
  3. บล็อกข้อความและ String.format
  4. นิพจน์ทั่วไปด้วย Pattern และ Matcher
← กลับไปที่ Java Academy