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

Possessive Quantifier — *+ ++ ?+

~10 min · possessive, no-backtrack, performance

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

이 quantifier 의 backtracking 비활성화

Possessive quantifier — *+, ++, ?+, {n,m}+ 로 작성 — greedy 처럼 매칭, 하지만 한 번 소비하면 돌려주길 거부. 이 quantifier 통한 backtracking 없음.

제한적으로 들리지만, 빠르고 ReDoS-safe 패턴 작성 비결. Backtracking 이 적대적 입력에 정규식 느려지게 하는 것. backtracking 도움 안 되는 자리에서 비활성화하면 엔진이 날아.

성능 win

패턴 a+b 입력 aaaaaaa: greedy a+ 가 a 7개 다 잡음, b 매칭 못 함, 한 a 씩 backtrack (7번 시도) 후 실패. Possessive a++b: a 7개 다 잡음, b 매칭 못 함, backtrack 거부, 즉시 실패. 같은 결과, 훨씬 적은 일.

ReDoS 보호 (트랙 8) 에 이게 전부. (a+)+b 같은 패턴은 지수적 — a+ 가 외부 + 로 backtrack 가능하니까. Possessive 로 — (a++)+b — 만들면 linear.

Flavor 지원

Possessive quantifier 는 PCRE, Java, Ruby (1.9+), .NET (5+) 에 존재. Python re 는 없음 (추가하는 regex 모듈 사용) 또는 JavaScript 에 없음. RE2 는 backtrack 자체 안 해서 필요 없음.

엔진이 possessive 미지원이면 등가는 atomic group (?>...), 트랙 8 에서.

Code

Possessive quantifier (PCRE/Java/Ruby)·text
# Java 에서
Pattern.matches("a++b", "aaaaaaa")  // false, backtracking 시도 없음

# PHP/PCRE 에서
preg_match('/a++b/', 'aaaaaaa')  // 0

# Python 에서 (third-party 'regex' 라이브러리 필요, 내장 're' 아님)
import regex
regex.findall(r'a++b', 'aaaaaaa')  # []  — 빠르게 실패

# Atomic group 등가 — Python re 에서도 동작
import re
re.findall(r'(?>a+)b', 'aaaaaaa')  # re 가 atomic group 지원하면

# 큰 입력에서 성능 차이 보임
# 'a' * 30 + 'X'  — 적대적 입력
# (a+)+ → 지수 시간, 분 단위로 멈출 수 있음
# (a++)+ → linear 시간, 즉시 실패

External links

Exercise

Python 3.11+ 면 re.match(r'(a+)+b', 'a' * 30) 시간 측정. 그 다음 re.match(r'(?>a+)+b', 'a' * 30). Atomic group 이 즉시 끝나야, 원본은 멈출 수 있음. 이게 ReDoS 보호 메커니즘.

Progress

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

댓글 0

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

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