DT

정규식 테스터 & 치트시트

패턴을 입력하는 즉시 매치·캡처 그룹·치환 결과를 확인합니다.

이 도구는 100% 브라우저에서 실행됩니다. 입력한 데이터는 서버로 전송되지 않습니다.

정규식은 한 줄에 많은 것을 담을 수 있어 강력하지만, 그만큼 눈으로 검증하기 어렵습니다. \d{3}-\d{4} 가 의도한 문자열을 모두 잡는지, 잡지 말아야 할 것까지 잡지는 않는지는 실제 데이터에 돌려 봐야 알 수 있습니다.

이 도구는 패턴을 입력하는 즉시 테스트 문자열에서 일치하는 부분을 하이라이트로 보여 주고, 매치 위치·캡처 그룹·이름 있는 그룹을 표로 정리하며, 치환 결과까지 미리 확인시켜 줍니다. 이메일·URL·IPv4·한국 휴대폰 번호·UUID 같은 자주 쓰는 패턴은 버튼 한 번으로 불러올 수 있고, 아래에는 문법 치트시트가 항상 펼쳐져 있습니다.

사용 방법

  1. 패턴과 플래그 설정슬래시 사이에 정규식을 입력하고 필요한 플래그를 체크합니다. g(전역)는 모든 매치를 찾고, i는 대소문자를 무시하며, m^·$가 각 줄의 시작과 끝에 맞도록 바꿉니다. 문법 오류가 있으면 입력창 아래에 원인이 표시됩니다.
  2. 테스트 문자열 준비실제 데이터와 비슷한 문자열을 넣습니다. 잡혀야 할 예시와 잡히면 안 되는 예시를 함께 넣는 것이 중요합니다. 정규식 버그의 대부분은 못 잡는 것이 아니라 과하게 잡는 데서 나옵니다.
  3. 하이라이트와 목록으로 검증하이라이트 탭에서 매치된 구간을 눈으로 확인하고, 목록 탭에서 각 매치의 인덱스와 캡처 그룹 값을 확인합니다. 그룹이 undefined 로 나온다면 해당 그룹이 선택적(?)이거나 다른 분기에 있다는 뜻입니다.
  4. 치환 결과 미리보기치환 탭에서 $1, $&, $<name> 같은 참조를 써서 결과를 미리 확인합니다. $&는 매치 전체, $1은 첫 번째 캡처 그룹, $<name>은 이름 있는 그룹을 가리킵니다.

자주 묻는 질문

여기서 만든 정규식을 Python이나 Java에서도 쓸 수 있나요?

이 도구는 자바스크립트(ECMAScript) 정규식 엔진을 사용합니다. 기본 문법은 대부분의 언어에서 동일하게 동작합니다.

다만 세부적으로 다른 부분이 있습니다. 자바스크립트에는 \A·\z 같은 절대 경계가 없고 ^·$로 대신합니다. \d 는 기본적으로 ASCII 숫자만 뜻하지만 Python은 유니코드 숫자까지 포함합니다. 이름 있는 그룹은 자바스크립트·Python·Java 모두 (?<name>...) 문법을 쓰지만, Python의 치환 참조는 $<name> 이 아니라 \g<name> 입니다.

매치가 하나만 나오고 멈춥니다.

g(global) 플래그가 꺼져 있는지 확인하세요.

g 없이 execmatch를 호출하면 첫 번째 매치만 돌려주고 끝납니다. 이 도구도 같은 규칙을 따르므로 모든 매치를 보려면 g를 켜야 합니다. 반대로 코드에서 test() 를 반복 호출할 때 g 플래그가 켜져 있으면 lastIndex 가 유지되어 결과가 번갈아 나오는 유명한 함정이 있으니, 단순 존재 여부 검사에는 g 를 빼는 편이 안전합니다.

정규식이 갑자기 멈춘 것처럼 느려집니다.

치명적 백트래킹(catastrophic backtracking)일 가능성이 높습니다.

(a+)+b 처럼 중첩된 수량자가 있는 패턴에 긴 문자열을 넣으면, 엔진이 시도해야 할 경우의 수가 입력 길이에 대해 지수적으로 늘어납니다. 실제 서비스에서는 이것이 ReDoS라는 서비스 거부 취약점이 됩니다. 중첩 수량자를 피하고, .* 대신 [^"]* 처럼 범위를 좁히고, 가능하면 사용자 입력을 정규식에 직접 넣지 마세요.

알아두면 좋은 개념

탐욕적 수량자와 게으른 수량자

*·+·{n,m} 은 기본적으로 탐욕적입니다. 가능한 한 길게 잡은 뒤 필요한 만큼 되돌립니다. 그래서 <.*><b>bold</b> 에 적용하면 <b> 만이 아니라 문자열 전체가 잡힙니다.

뒤에 ? 를 붙이면 게으른 수량자가 되어 가능한 한 짧게 잡습니다. <.*?><b></b> 를 각각 잡습니다. HTML 태그, 따옴표 안의 문자열, 로그의 대괄호 구간처럼 구분자가 반복되는 데이터를 다룰 때는 이 차이를 아는 것만으로 대부분의 문제가 해결됩니다.

캡처 그룹, 비캡처 그룹, 이름 있는 그룹

(...) 는 매치된 부분을 저장하는 캡처 그룹입니다. 저장이 필요 없고 묶기만 하려면 (?:...) 를 쓰는 편이 낫습니다. 불필요한 캡처는 결과를 읽기 어렵게 만들고 아주 약간이지만 성능에도 영향을 줍니다.

그룹이 많아지면 $1·$2 로 세는 일이 고통스러워집니다. (?<year>\d{4})-(?<month>\d{2}) 처럼 이름을 붙여 두면 코드에서 match.groups.year 로 접근할 수 있어 나중에 그룹을 추가해도 깨지지 않습니다.

전방 탐색과 후방 탐색

(?=...) 는 '뒤에 이것이 오지만 매치에는 포함하지 않는다'는 뜻이고, (?!...) 는 그 부정입니다. (?<=...)·(?<!...) 는 앞쪽을 보는 형태입니다.

비밀번호 규칙 검사처럼 여러 조건을 동시에 만족시켜야 할 때 특히 유용합니다. ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$ 는 '소문자·대문자·숫자를 각각 하나 이상 포함하는 8자 이상'을 한 줄로 표현합니다. 각 전방 탐색이 문자를 소비하지 않으므로 같은 위치에서 조건을 겹쳐 확인할 수 있습니다.

함께 쓰면 좋은 도구

최종 업데이트: 2026-08-12