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

부정형 후방 탐색 — (?<!...)

~8 min · lookbehind, negative

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

부정형 후방 탐색은 앞쪽에 금지할 모양을 적어

(?<!...)는 현재 위치 바로 앞의 텍스트가 안쪽 패턴과 맞지 않을 때만 성공해. 원하지 않는 접두사가 붙은 경우를 매칭 전에 제외할 수 있지.

처리된 항목을 건너뛸 수 있어

예를 들어 DONE-이 붙지 않은 TODO만 찾고 싶다면 부정형 후방 탐색으로 그 접두사를 막을 수 있어. 패턴이 복잡해지면 넓게 찾은 뒤 코드에서 접두사를 검사하는 두 단계 방식이 더 읽기 쉬울 수도 있어.

문장 경계 예시에는 너비 함정이 숨어 있어

(?<!Mr|Mrs|Dr)\.\s+[A-Z]는 호칭 뒤의 점을 문장 끝으로 보지 않으려는 의도야. 하지만 대안의 길이가 2, 3, 2로 서로 달라서 Python 내장 re에서는 이 패턴 자체가 컴파일되지 않아.

부정형도 같은 고정 길이 제약을 받아

Python re에서는 각 고정 길이 조건을 별도 후방 탐색으로 나누거나, 앞쪽 표현까지 넓게 매칭한 뒤 코드에서 후보를 거르는 식으로 다시 설계해. 가변 길이 후방 탐색이 꼭 필요하다면 별도 regex 모듈처럼 이를 지원하는 엔진을 선택할 수 있어.

앵커도 후방 조건에 사용할 수 있어

(?<!^)는 현재 위치가 문자열 시작이 아닐 때 성공해. 이런 조건을 이용하면 토큰은 찾되 시작 위치의 토큰만 제외하는 식으로 위치에 따른 규칙을 만들 수 있어.

Code

부정형 후방 탐색 패턴·python
import re

# '$'가 붙은 가격은 건너뛰고 독립 숫자만 찾기
# 앞 문자가 '$' 또는 숫자면 시작하지 못하게 해 $20 안의 0도 막아.
re.findall(r'(?<![\d$])\d+', 'cost $20 plus 5 shipping and $3 tax')
# ['5']

# 'a '가 바로 앞에 오는 'cat' 제외
re.findall(r'(?<!a )cat', 'a cat saw a cat and the cat ran')
# ['cat']  — 세 번째만 ('the ' 앞)

# 'DONE-'이 바로 앞에 오는 'TODO' 제외
re.findall(r'(?<!DONE-)TODO', 'TODO fix this DONE-TODO already done')
# ['TODO']

# 줄 시작이 아닌 숫자 (re.MULTILINE)
re.findall(r'(?<!^)\d+', '5 a 10 b 15', flags=re.MULTILINE)
# ['10', '15']  — '5'는 한 줄짜리 입력의 시작

External links

Exercise

바로 앞에 // # 가 붙지 않은 단어 fix를 찾는 패턴을 작성해. 이 검사가 주석 전체의 문맥을 판별하는 것과 왜 다른지 적고, 정확한 주석 제외에는 토크나이저나 파서가 필요한 이유도 설명해.

Progress

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

댓글 0

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

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