0Pricing
Java Academy · 강의

Pattern과 Matcher를 사용한 정규 표현식

Java 정규 표현식을 사용해 이메일을 검증하고 부분 문자열을 추출하며 패턴을 대체합니다.

Pattern과 Matcher를 사용한 정규 표현식은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

Pattern과 Matcher를 사용한 정규 표현식

Java의 java.util.regex 패키지는 강력한 텍스트 검색, 검증, 추출 및 대체 기능을 위한 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()는 문자열 전체를 테스트합니다. find()는 문자열 안에서 다음으로 일치하는 항목을 찾습니다. 검색에는 find를 사용하고, 전체 검증에는 matches를 사용합니다.

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]

Pattern 플래그

플래그는 정규 표현식의 동작을 변경합니다: CASE_INSENSITIVE, 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는 문자열에 대해 테스트합니다
  • matches()는 문자열 전체를 검증하고, find()는 일치 항목을 검색합니다
  • 캡처 그룹 ()은 부분 문자열을 추출하며, group(n) 또는 group("name")으로 접근합니다
  • 이름이 지정된 그룹 (?<name>...)을 사용하면 패턴을 더 읽기 쉽게 만들 수 있습니다
  • replaceAll()과 split()은 유연한 텍스트 조작을 위해 정규 표현식 패턴을 인수로 받습니다
  • Pattern.CASE_INSENSITIVE, MULTILINE, DOTALL 플래그를 사용하여 일치 동작을 변경합니다

자주 묻는 질문

“Pattern과 Matcher를 사용한 정규 표현식” 강의는 무료인가요?

네 — “Pattern과 Matcher를 사용한 정규 표현식” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“Pattern과 Matcher를 사용한 정규 표현식”에서 뭘 배우나요?

Java 정규 표현식을 사용해 이메일을 검증하고 부분 문자열을 추출하며 패턴을 대체합니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Java Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“Pattern과 Matcher를 사용한 정규 표현식” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 문자열 불변성과 문자열 풀
  2. 효율적인 연결을 위한 StringBuilder
  3. 텍스트 블록과 String.format
  4. Pattern과 Matcher를 사용한 정규 표현식
← Java Academy(으)로 돌아가기