C.W.K.
Stream
Lesson 10 of 12 · published

흔한 quantifier 실수

~8 min · mistakes, debugging

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

모두가 한 번씩 하는 다섯 실수

1. + 의도에 * 사용. 검증기가 빈 입력 받음. 수정: 콘텐츠 필수면 +.

2. 마커 사이 추출에 greedy .*. 의도 끝점 지나서 먹음. 수정: lazy .*? 또는 negated class [^X]*.

3. 패턴 끝의 \d+ anchor 없이. 부분 숫자 매칭. 수정: \b 또는 $ 로 anchor.

4. ? 가 잘못된 거에 적용. foo?bar 는 두 번째 o 만 optional, 'foo' 가 아님. 'foo' optional 로 만들려면 group: (foo)?bar.

5. 공백 있는 {3,}. 공백 있는 {3, } 는 일부 flavor 에서 리터럴 텍스트로 해석. 항상 타이트: {3,}.

Quantifier 이슈 디버깅

패턴이 "테스트 데이터엔 동작하는데 production 에 실패" 할 때, 원인은 거의 항상:

  • Anchor 없는 quantifier 가 기대보다 적게 매칭.
  • Greedy quantifier 가 의도 경계 지나서 먹음.
  • * 가 테스트 데이터엔 없던 빈 입력 기쁘게 매칭.

임시 anchor 추가, 생각할 수 있는 가장 적대적 입력에 테스트 (빈 문자열, 매우 긴 문자열, 단 한 글자, 구분자만 콘텐츠 없음).

Code

다섯 흔한 실수·python
import re

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

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

# 실수 3: anchor 없는 \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' 만 optional
re.findall(r'(foo)?bar', 'bar fobar foobar')
# ['', '', 'foo']  — 'foo' 전체 optional

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

External links

Exercise

본인 코드베이스에서 quantifier 하나 찾기. 다섯 적대적 입력 (빈 거, 공백만, 매우 김, 구분자만, 정확히 한 글자) 테스트. 놀람 메모하고 수정.

Progress

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

댓글 0

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

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