정규식 테스트 도구
정규식을 실시간으로 테스트하고 디버깅, 매칭 결과 강조 및 코드 생성
정규식이란?
정규식(Regular Expression, regex 또는 regexp)은 텍스트를 매칭, 검색, 치환하는 강력한 도구입니다. 특정한 문법 규칙을 사용하여 텍스트 패턴을 기술하고, 입력 형식을 빠르게 검증하거나, 특정 내용을 추출하고, 일괄 치환 등을 수행할 수 있습니다. 정규식은 프로그래밍, 데이터 처리, 텍스트 편집 등의 시나리오에서 널리 사용됩니다.
사용 방법
사용 방법
- 왼쪽 입력란에 정규식 패턴을 입력하세요
- 필요한 플래그를 선택하세요 (예: g는 전역, i는 대소문자 무시)
- 오른쪽에 테스트 텍스트를 입력하세요
- 강조 표시된 일치 항목과 세부 정보를 확인하세요
정규식 팁
- 일치하는 예와 일치하지 않는 예로 모두 테스트해 보면 너무 넓은 패턴을 더 쉽게 발견할 수 있습니다.
- 긴 텍스트에서 중첩 수량자는 주의하세요. 일부 패턴은 과도한 백트래킹 때문에 느려질 수 있습니다.
활용 사례
기술 원리
테스터는 ECMAScript 언어 명세에 정의된 RegExp 엔진에 의해 구동됩니다. ECMAScript 정규식은 백트래킹 NFA 구현입니다. 엔진은 각 대안을 왼쪽에서 오른쪽 순서로 시도하고 수량자 실패 시 되돌아가며, 이것이 룩어라운드와 역참조를 가능하게 하지만 적대적 입력에서 대재앙적 백트래킹을 유발하기도 합니다. 엔진이 인식하는 여섯 가지 플래그는 g(전역), i(대소문자 무시), m(다중 줄, 줄별 앵커), s(dotAll, '.'이 줄바꿈 매칭), u(유니코드 모드), y(스티키, lastIndex에 앵커)입니다. 플래그에 따라 매칭 시맨틱스가 크게 변합니다. /u 하에서 엔진은 패턴을 UTF-16 코드 유닛이 아닌 유니코드 코드 포인트의 시퀀스로 취급하므로 서러게이트 페어가 하나의 문자로 매칭되고, \p{L}(모든 문자), \p{Sc}(통화 기호), \p{Script=Han} 같은 유니코드 속성 클래스를 사용할 수 있습니다. 명명된 캡처 그룹 (?<name>...)과 룩비하인드 (?<=...)는 ES2018의 일부이며 Chromium 64+, Firefox 78+, Safari 16.4+에서 지원되지만, 아토믹 그룹 (?>...)과 포세시브 수량자 (a++) 같은 PCRE 전용 기능은 아직 명세에 포함되어 있지 않습니다. 프로덕션에서 가장 큰 위험은 ReDoS입니다. 입력 'aaaaaaaaaaaaaaaa!'에 대한 (a+)+b 같은 패턴은 두 개의 중첩 수량자가 같은 문자 시퀀스를 여러 방식으로 분할할 수 있어 지수적 경로를 탐색합니다. 완화 방법은 잘 알려져 있습니다. 같은 문자 클래스에 대한 중첩 수량자를 피하고, 가능한 한 ^와 $로 앵커링하며, 엔진이 지원하면 아토믹 그룹을 선호하거나, Go의 RE2(역참조와 룩비하인드를 O(n) 보장 매칭으로 교환)와 같은 선형 시간 엔진으로 전환합니다. 서버 측 검증을 위한 신뢰할 수 없는 입력의 경우 RE2 또는 수작업 파서가 거의 항상 더 안전한 선택입니다.
- 엔진: ECMAScript RegExp는 DFA가 아닌 백트래킹 NFA; 이것이 룩어라운드와 역참조를 가능하게 하지만 대재앙적 백트래킹도 가능하게 함
- 플래그: g(전역), i(대소문자 무시), m(줄별 ^/$), s(dotAll, '.'이 \n 매칭), u(유니코드 모드, 서러게이트 인식), y(스티키, lastIndex에 앵커)
- 유니코드 모드: /u가 코드 포인트 매칭과 \p{L}(문자), \p{Sc}(통화), \p{Script=Han}을 활성화; /u 없이는 [a-zA-Z]+가 비라틴어 단어를 모두 놓침
- 최신 구문 가용성: 명명된 캡처 (?<n>...)와 룩비하인드 (?<=...)는 Chromium 64+, Firefox 78+, Safari 16.4+에서 지원; 아토믹 그룹 (?>...)과 포세시브 수량자 (a++)는 ECMAScript에 없음
- ReDoS: 같은 클래스에 대한 중첩 수량자 (a+)+b가 지수적으로 폭발; 앵커, 아토믹 그룹으로 강화하거나 신뢰할 수 없는 입력에 RE2/re2-wasm으로 마이그레이션
- 복잡도 하한: 고정 알파벳에 대한 리터럴 앵커 패턴은 O(n)으로 실행; 역참조와 제한 없는 룩어라운드는 최악의 경우를 지수적으로 밀어올리므로 배포 전 적대적 입력으로 벤치마크할 것
예시
이메일 주소 매칭
패턴: ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$
플래그: gi
입력: contact: alice@example.com, bob_2024@mail.co.uk, invalid@.com
일치: alice@example.com, bob_2024@mail.co.uk (2건)로그에서 IPv4 주소 추출
패턴: \b(?:\d{1,3}\.){3}\d{1,3}\b
플래그: g
입력: 2026-06-15 ERROR client 192.168.1.42 connect failed (peer 10.0.0.1)
일치: 192.168.1.42, 10.0.0.1명명된 그룹으로 날짜 부분 캡처
패턴: (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
플래그: g
입력: Sprint window: 2026-09-01 to 2026-09-15
그룹: {year:'2026', month:'09', day:'01'}, {year:'2026', month:'09', day:'15'}탐욕적 vs 게으른 수량자
입력: <b>hello</b> <i>world</i>
.* (탐욕적) -> 줄 전체와 일치: <b>hello</b> <i>world</i>
.*? (게으른) -> 첫 번째만 일치: <b>hello</b>
태그 사이의 내용을 추출할 때는 보통 게으른 수량자가 적합합니다.유니코드 인식 문자 클래스
패턴: \p{L}+
플래그: gu
입력: Hello, 北京! Café Москва
일치: Hello, 北京, Café, Россия
u 플래그와 \p{L} 없이 [a-zA-Z]+만 쓰면 라틴 문자가 아닌 모든 단어를 놓치게 됩니다.자주 묻는 질문
이 도구는 어떤 정규식 문법을 사용하나요?
JavaScript의 정규식 엔진(ECMAScript)을 사용합니다. 일반적인 기능은 PCRE와 비슷하지만 엣지 케이스에서 차이가 납니다. 소유격 수량자가 없고, 재귀가 없으며, lookbehind는 최신 브라우저에서만 동작하고, 명명 그룹은 (?<name>...) 형태입니다. Python(re/regex), Java, .NET, PCRE 등에서는 동일한 패턴이 다르게 동작할 수 있으니 실제 환경에서도 테스트하세요.
어떤 플래그를 지원하나요?
g(전역, 모든 매치 찾기), i(대소문자 무시), m(다중 행, ^과 $가 행 경계와 일치), s(dotall, .이 줄바꿈과 매치), u(유니코드), y(sticky), d(hasIndices)를 지원합니다. 토글 행에서 선택하면 각각이 테스트 텍스트에서 어떻게 동작이 달라지는지 페이지가 보여줍니다.
왜 예상보다 매치 수가 적게 나오나요?
g 플래그가 없으면 regex.exec는 한 매치만 반환합니다. m이 없으면 ^과 $가 입력 전체의 처음·끝에서만 매치됩니다. u가 없으면 서로게이트 페어 문자(이모지)가 두 절반으로 나뉘어 매치됩니다. '왜 안 되지?' 문제의 대부분은 플래그 누락입니다.
이모지나 한자·일본어·한글은 어떻게 매치하나요?
u 플래그를 켜서 적절한 유니코드 처리를 활성화하세요. 유니코드 속성으로 매치하려면 \p{...} 문자 클래스(\p{Letter}, \p{Script=Han}, \p{Emoji} 등)를 쓰세요. u 없이는 [a-zA-Z]가 악센트 문자도 매치하지 못합니다. [a-zA-ZÀ-ÿ]로 확장하거나 \p{L}을 사용하세요.
패턴에서 코드를 생성할 수 있나요?
대부분의 빌드는 적절한 이스케이프와 함께 패턴을 JavaScript, Python, PHP, Ruby, Go, Java 문법으로 내보냅니다. 다만 같은 패턴이라도 엔진에 따라 동작이 달라질 수 있다는 점(탐욕 기본값, 문자 클래스 동작, lookaround 지원 여부 등)을 유의하고, 항상 대상 언어에서 다시 테스트하세요.
탐욕(greedy)과 게으른(lazy) 수량자의 차이는?
탐욕(* + ?)은 가능한 한 많이 매치하고 필요하면 백트래킹합니다. 게으름(*? +? ??)은 가능한 한 적게 매치합니다. 'A와 B 사이의 모든 것 추출'에서 B가 여러 개라면 탐욕 .*는 너무 멀리까지 가버리고, 게으른 .*?는 첫 B에서 멈춥니다. 안쪽 내용을 추출할 때는 게으른 쪽을 기본으로 쓰세요.
내 정규식이나 테스트 텍스트가 업로드되나요?
아니요. 매칭은 JavaScript의 네이티브 정규식 엔진으로 브라우저 안에서만 실행됩니다. 패턴과 입력은 외부로 전송되지 않습니다.