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

흔한 수량자 실수

~8 min · mistakes, debugging

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

자주 만나는 다섯 가지 실수

1. 하나 이상이 필요한데 *를 사용해. 빈 입력도 통과해 버려. 내용이 반드시 있어야 한다면 +를 써.

2. 두 마커 사이를 탐욕적 .*로 잡아. 의도한 끝점을 지나칠 수 있어. .*?나 경계를 직접 표현한 부정형 문자 클래스를 검토해.

3. 패턴 끝의 \d+에 경계를 붙이지 않아. 더 긴 토큰의 일부 숫자도 매칭할 수 있어. 상황에 맞게 \b$를 붙여.

4. ?를 잘못된 요소에 붙여. foo?bar에서 선택적인 것은 두 번째 o 하나뿐이야. foo 전체를 선택적으로 만들려면 (foo)?bar라고 써.

5. {3,} 안에 공백을 넣어. {3, }는 엔진에 따라 리터럴 텍스트로 해석될 수 있어. 범위 수량자 안에는 공백을 넣지 마.

수량자 문제를 디버깅하는 순서

테스트 데이터에서는 되는데 실서비스에서 실패한다면 먼저 경계, 탐욕성, 빈 입력 허용 여부를 확인해. 임시 앵커를 붙이고 빈 문자열, 공백만 있는 문자열, 아주 긴 문자열, 구분자만 있는 문자열, 한 글자 입력을 차례로 넣어 보면 원인이 빨리 드러나.

Code

다섯 흔한 실수·python
import re

# 실수 1: * 가 빈 거 받아들임
bool(re.fullmatch(r'\d*', ''))   # True (아마 잘못)
bool(re.fullmatch(r'\d+', ''))   # False (아마 맞음)

# 실수 2: 탐욕적 .* 가 너무 먹음
re.findall(r'".*"', '"a" or "b"')  # ['"a" or "b"']
re.findall(r'"[^"]*"', '"a" or "b"')  # ['"a"', '"b"']

# 실수 3: 앵커 없는 \d+
re.findall(r'\d+', 'order #1234X567 cost $99')
# ['1234', '567', '99']  — 1234X567 분리

# 실수 4: 잘못된 글자에 ?
re.findall(r'foo?bar', 'fobar foobar fooobar')
# ['fobar', 'foobar']  — 두 번째 'o' 만 선택적
re.findall(r'(foo)?bar', 'bar fobar foobar')
# ['', '', 'foo']  — 'foo' 전체 optional

# 실수 5: 공백 있는 {n, m} (일부 flavor 에서 조용히 실패)

External links

Exercise

코드에서 수량자가 들어간 패턴 하나를 골라 빈 문자열, 공백만 있는 문자열, 매우 긴 문자열, 구분자만 있는 문자열, 한 글자짜리 문자열을 시험해. 예상과 다른 결과를 기록하고 수량자나 경계를 고친 뒤 같은 입력을 다시 실행해.

Progress

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

댓글 0

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

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