본문 바로가기
C.W.K.
Stream
Lesson 06 of 12 · published

탐욕적 매칭 — 기본 동작

~10 min · greedy, engine

Level 0패턴 호기심
0 XP0/90 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

수량자는 기본적으로 가능한 만큼 잡아

수량자는 별도 표시가 없으면 탐욕적으로 동작해. 먼저 가능한 만큼 문자를 소비하고, 뒤에 남은 패턴이 실패할 때만 조금씩 되돌려 줘.

a.*ba123b456b에 적용해 보자. 첫 번째 b에서 멈출 것 같지만 실제로는 첫 a부터 마지막 b까지인 a123b456b를 매칭해.

왜 마지막 b까지 갈까

엔진은 .*로 문자열 끝까지 소비한 다음 리터럴 b를 맞추려 해. 끝에서는 실패하므로 한 글자씩 되돌아가며 다시 시도하고, 가장 먼저 성공하는 마지막 b에서 멈춰. 이 순서를 기억하면 탐욕적 수량자의 결과를 훨씬 쉽게 예측할 수 있어.

두 마커 사이를 찾을 때 생기는 함정

.*로 시작 마커와 끝 마커 사이를 추출하면 의도한 첫 끝점을 지나 마지막 끝점까지 먹기 쉬워. 다음 강의 게으른 수량자나, 경계를 직접 적는 부정형 문자 클래스로 범위를 분명히 만들어.

Code

탐욕적 슬로우모션·python
import re

# 탐욕적: 가능한 가장 긴 부분 문자열 매칭
re.findall(r'a.*b', 'a123b456b')
# ['a123b456b']  — 'a123b' 만이 아님

# HTML 도 — 재앙
html = '<p>first</p> <p>second</p>'
re.findall(r'<p>.*</p>', html)
# ['<p>first</p> <p>second</p>']  — 두 문단 한 매칭으로 먹음

# Greedy + backtracking 시각화
# 패턴: a\d+b 입력 'a12345b6789b' 에 대해
# 1. \d+ 가 '12345b6789' 잡음  → 다음 글자 'b' 여야 함, 위치는 끝 너머
# 2. 한 글자 backtrack: \d+ 가 '12345b678' 됨  → 여전히 'b' 안 옴, 잠깐
# 3. 사실 \d+ 가 'b' 잡을 수 없음 (숫자 아님), 그래서 '12345' 만 잡음
# 4. 그 다음 'b' 가 위치 6 에서 매칭
re.findall(r'a\d+b', 'a12345b6789b')
# ['a12345b']  — \d+ 가 처음부터 b 포함 못 해

External links

Exercise

re.findall(r'".*"', '"a" "b" "c"')의 결과를 예측한 뒤 실행해. 탐욕적 .*가 여러 따옴표 구간을 한꺼번에 잡는 이유를 결과의 시작과 끝 위치로 설명해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.