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

조건 패턴 — (?(N)yes|no)

~8 min · conditional, advanced, pcre

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

앞 그룹이 참여했는지에 따라 뒤 패턴을 고를 수 있어

(?(N)yes|no)는 그룹 N이 캡처에 참여했다면 yes를, 아니면 no를 적용해. 이름 붙은 그룹은 (?(name)yes|no)처럼 참조할 수 있어.

예를 들어 여는 따옴표를 선택 사항으로 두되, 실제로 열었다면 같은 종류의 닫는 따옴표를 요구하는 규칙을 만들 수 있지.

선택적인 괄호도 짝을 맞출 수 있어

^(\()?\d+(?(1)\))$는 여는 괄호가 캡처됐을 때만 닫는 괄호를 요구해. 전체 문자열을 검사하므로 123(123)은 성공하지만 (123123)은 실패해.

모든 엔진이 조건 패턴을 지원하지는 않아

Python re, PCRE, Perl, .NET, PHP, Ruby는 조건 패턴을 지원해. JavaScript, Go, RE2에서는 사용할 수 없어.

선택으로 더 단순하게 쓸 수 있는지 먼저 봐

위 예시는 (?:\(\d+\)|\d+)처럼 괄호가 있는 전체 모양과 없는 전체 모양을 선택으로 나눠도 표현할 수 있어. 조건 패턴은 두 분기가 긴 공통 부분을 공유해서 선택으로 쓰면 중복이 심해질 때 가치가 커. 짧은 패턴이라면 더 널리 지원되고 읽기 쉬운 선택을 먼저 고려해.

Code

조건 패턴·python
import re

# 괄호 쌍: 열고 닫음 함께, 또는 둘 다 없음
pattern = r'(\()?\d+(?(1)\))'
bool(re.fullmatch(pattern, '123'))    # True
bool(re.fullmatch(pattern, '(123)'))  # True
bool(re.fullmatch(pattern, '(123'))   # False
bool(re.fullmatch(pattern, '123)'))   # False

# Named 그룹 조건
pattern = r'(?P<bracket>\()?\d+(?(bracket)\))'
bool(re.fullmatch(pattern, '(42)'))   # True

# 조건 없는 등가 — 보통 더 깨끗
pattern = r'\(\d+\)|\d+'
bool(re.fullmatch(pattern, '(42)'))   # True
bool(re.fullmatch(pattern, '42'))     # True

External links

Exercise

(415-555-0199)처럼 괄호 완전 감싸기 또는 415-555-0199처럼 괄호 없이 단독인 전화번호 매칭하는 패턴 — 한쪽 괄호만은 지원하지 않아. 먼저 선택으로 풀고, 그다음 조건 패턴으로 다시 풀어 봐. 두 패턴의 가독성을 비교해.

Progress

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

댓글 0

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

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