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

Lookahead 와 Lookbehind 결합

~8 min · combining, advanced

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

양쪽 assertion 으로 매칭 wrap

같은 위치에 lookbehind 와 lookahead 둘 다 stack 가능, 양쪽 다 소비 없이 주장. 외과적 추출에 유용.

예시: 고정 구분자 사이 값 추출

"[] 사이 텍스트 가져오기, 안의 텍스트만 반환."

(?<=\[)[^\]]+(?=\])
  • (?<=\[) — 여는 대괄호 앞에 옴 주장
  • [^\]]+ — 실제 콘텐츠 매칭 (닫는 대괄호 빼고 어떤 거든)
  • (?=\]) — 닫는 대괄호 따라옴 주장

매칭이 안의 콘텐츠만. 대괄호는 감지되지만 제외.

캡처 그룹으로 같은 거, 덜 우아

Lookaround 없이: \[([^\]]+)\] — 대괄호 매칭, 안 캡처. 그 다음 m.group(1) 접근. 기능적으로 등가; 가독성 비용이 패턴과 코드 사이 이동.

Wrapped lookaround 선호 시기

다음일 때 wrapped lookaround:

  • findall 이 튜플 unpack 없이 깨끗한 값 반환 원할 때.
  • 같은 패턴을 캡처 그룹 어색한 `sed` 또는 `ripgrep --replace` 에 재사용 원할 때.
  • 패턴이 더 복잡한 정규식의 일부고 관리할 캡처 슬롯 하나 적게 원할 때.

캡처 그룹 선호 시기

다음일 때 캡처 그룹:

  • 본인 엔진이 lookbehind 미지원 (Go, RE2).
  • Lookbehind 가 variable-width 필요고 본인 엔진이 제약.
  • 치환 위해 주변 텍스트 접근 원할 때 (예: sub 에서 대괄호로 wrap).

Code

Wrapped lookaround vs 캡처·python
import re

# Wrapped lookaround — 깨끗한 값
re.findall(r'(?<=\[)[^\]]+(?=\])', '[apple] [banana] [cherry]')
# ['apple', 'banana', 'cherry']

# 캡처 그룹 등가 — 튜플 또는 추가 unpacking
re.findall(r'\[([^\]]+)\]', '[apple] [banana] [cherry]')
# ['apple', 'banana', 'cherry']  — 그룹 한 개 findall 이 flatten 해서 같음

# 두 특정 마커 사이 단어
re.findall(r'(?<=ID:)\w+(?= accepted)', 'ID:abc123 accepted ID:def456 rejected')
# ['abc123']  — accepted 만

# 실전: 템플릿 변수명 추출
# {{username}} 또는 {{ user.name }} → 'username' 또는 'user.name'
re.findall(r'(?<=\{\{)\s*([\w.]+)\s*(?=\}\})', 'Hello {{ user.name }}, welcome {{username}}')
# ['user.name', 'username']  — lookaround 안 캡처 사용

External links

Exercise

문자열에서 {{name}} 같은 모든 템플릿 placeholder 찾고 중괄호 없는 안 이름 반환하는 단일 정규식 작성. Hi {{user}}, your order {{order_id}} is ready 테스트. 결과: ['user', 'order_id'].

Progress

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

댓글 0

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

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