정규식 테스터는 패턴이 글의 어디에 맞는지 바로 보여 줍니다
정규식(정규 표현식, regular expression)은 글에서 찾을 모양을 기호로 적은 규칙입니다. \d{4}는 '숫자 4개', [가-힣]+는 '한글 음절 1개 이상'을 뜻합니다. 규칙은 짧지만 기호 하나만 달라져도 찾는 범위가 크게 바뀌기 때문에, 코드에 넣기 전에 실제 글에 대 보고 확인하는 과정이 필요합니다.
이 도구는 지금 쓰는 브라우저의 자바스크립트 정규식 엔진으로 패턴을 실제로 실행합니다. 일치한 곳은 글 위에 바로 칠하고, 캡처 그룹은 색으로 구분해 일치 표의 열로 정리합니다. 패턴은 칸마다 무슨 뜻인지 풀어서 보여 주므로, 남이 쓴 정규식을 읽고 이해할 때도 쓸 수 있습니다.
정규식을 코드에 넣기 전에 시험하는 이유
정규식이 틀리는 방식은 두 가지입니다. 찾아야 할 것을 놓치거나(휴대폰 번호 검사가 하이픈 없는 01012345678을 거절), 찾지 말아야 할 것까지 잡습니다(날짜 패턴이 2026-13-45도 받아들임). 둘 다 문법 오류가 아니어서 브라우저는 아무 경고도 내지 않습니다. 맞아야 할 예와 틀려야 할 예를 함께 넣어 보는 것이 가장 확실한 확인 방법입니다.
세 번째 문제는 속도입니다. 2019년 7월 2일 Cloudflare는 웹 방화벽(WAF) 규칙에 새 정규식을 배포했다가 백트래킹이 폭증해 HTTP 처리 CPU가 100% 가까이 차면서 27분 동안 서비스가 멈췄습니다. 회사가 공개한 사후 보고에 따르면 원인은 긴 패턴 안의 .*(?:.*=.*)라는 짧은 부분이었습니다. 같은 글을 찾는 패턴이라도 쓰는 방식에 따라 시도 횟수가 수백 배 넘게 늘 수 있으니, 실제 길이의 글로 시험해 봐야 합니다.
정규식을 미리 시험하면 좋은 상황은 다음과 같습니다.
- 입력 검증: 회원 가입 폼의 전화번호·이메일·비밀번호 조건을 정할 때, 통과해야 할 예와 막아야 할 예를 줄마다 넣어 봅니다.
- 값 뽑기: 로그·CSV·복사한 표에서 날짜, 주문 번호, IP 주소만 골라낼 때 그룹 값이 제대로 나뉘는지 봅니다. 일치 표는 그대로 스프레드시트에 붙여 넣을 수 있습니다.
- 일괄 바꾸기: 편집기나 코드에서 찾아 바꾸기를 돌리기 전에, 바뀌는 자리와 바뀐 결과를 미리 봅니다.
- 남이 쓴 정규식 읽기: 오래된 코드의 패턴이 무엇을 찾는지 칸마다 풀어 보고, 느려질 수 있는 모양이 있는지 확인합니다.
쓰는 법
- 패턴 칸에 정규식을 넣습니다. 앞뒤 슬래시는 쓰지 않습니다.
/abc/gi처럼 리터럴째 붙여 넣으면 패턴과 플래그로 나눠 넣습니다. - 오른쪽 글자 단추로 플래그를 켭니다. 여러 곳을 찾으려면
g를 켭니다. - 테스트할 글 칸에 글을 붙여 넣으면 일치한 곳이 바로 칠해지고, 위 상태 줄에 일치 수가 나옵니다.
- 입력 검증 패턴(
^…$)은 줄마다 따로를 켜고 예를 한 줄에 하나씩 넣습니다. 통과한 줄에는 ✓, 통과하지 못한 줄에는 ✗가 붙습니다. - 아래 일치 표에서 그룹 값을 보고, 번호 단추를 누르면 그 일치가 글에서 깜빡입니다. 바꾸기 탭에서는 바꿀 문자열을 넣어 결과를 보고, 코드 탭에서는 자바스크립트 코드로 옮겨 갈 수 있습니다.
패턴 해부 줄 읽는 법
패턴 해부 줄은 패턴을 엔진이 읽는 단위로 나눠 칸마다 위에는 원래 기호를, 아래에는 뜻을 적습니다. 수량자(+, {4} 등)는 앞 칸에 붙여서 '숫자 4번'처럼 함께 읽습니다. 칸 아래 굵은 선의 색은 그 칸이 속한 캡처 그룹이고, 같은 색이 글의 그룹 밑줄과 일치 표의 열 머리에도 쓰입니다. 점선 칸은 값을 저장하지 않는 묶음, 전방·후방탐색, '또는'입니다.
| 칸 | 뜻 | 그룹 색 |
|---|---|---|
(?<y> | 그룹 y 시작(1번 그룹) | 1번 색 |
\d{4} | 숫자 0~9를 4번 | 1번 색 |
) | 그룹 y 끝 | 1번 색 |
- | 하이픈 글자 그대로 | 없음 |
(?<m> \d{2} ) | 그룹 m: 숫자 2번 | 2번 색 |
주황 테두리 칸은 실행이 아주 느려질 수 있는 모양입니다. 반복 안에 다시 반복이 있는 (a+)+, 같은 반복이 연달아 붙은 .*.*를 찾아 표시합니다. 빨간 칸은 브라우저가 문법 오류로 거절한 패턴에서 오류 자리를 가리킵니다.
자주 쓰는 문법
아래 표의 '찾는 것'은 이 도구와 같은 자바스크립트 엔진으로 예시 글에 실제로 실행한 결과입니다.
| 기호 | 뜻 | 예 패턴 | 예시 글 | 찾는 것 |
|---|---|---|---|---|
\d | 숫자 0~9 한 글자 | \d+ | A동 102호 | 102 |
\w | 영문·숫자·밑줄(_) 한 글자 | \w+ | user_01 님 | user_01 |
. | 줄바꿈을 뺀 아무 글자 | a.c | abc a-c a↵c | abc, a-c |
[ ] | 괄호 안 글자 중 하나, -는 범위 | [가-힣]+ | Roberin 로베린 | 로베린 |
[^ ] | 괄호 안 글자를 뺀 하나 | [^0-9]+ | 010-1234 | - |
^ $ | 글(또는 줄)의 시작과 끝 | ^\d+$ | 2026 | 2026 |
{n,m} | 앞 칸을 n번 이상 m번 이하 | \d{2,3} | 1 22 333 4444 | 22, 333, 444 |
| | 또는 | cat|dog | hotdog cat | dog, cat |
\b | 단어 경계(영문·숫자 기준) | \bcat\b | cat category | cat |
(?= ) | 전방탐색: 뒤에 이것이 와야 함(그 글자는 일치에 넣지 않음) | \d+(?=원) | 3개 5000원 | 5000 |
(?<= ) | 후방탐색: 앞에 이것이 있어야 함 | (?<=\$)\d+ | $30 and 40 | 30 |
\1 | 1번 그룹에 잡힌 글을 한 번 더 | (\w)\1 | book keeper | oo, ee |
+? *? | 가능한 짧게 반복 | <.+?> | <b>x</b> | <b>, </b> |
플래그 8개가 바꾸는 것
플래그는 패턴 전체에 걸리는 설정입니다. 같은 패턴과 같은 글이라도 플래그에 따라 결과가 달라집니다.
| 플래그 | 하는 일 | 예 패턴 · 글 | 끈 결과 | 켠 결과 |
|---|---|---|---|---|
g | 첫 일치에서 멈추지 않고 모두 찾음 | a · a a a | a | a, a, a |
i | 대소문자를 같게 봄 | abc · ABC | 없음 | ABC |
m | ^ $가 줄마다 맞음 | ^\d · 1↵2 | 1 | 1, 2 |
s | .이 줄바꿈도 받음 | a.b · a↵b | 없음 | a↵b |
u | 이모지 같은 글자를 한 글자로 읽고 \p{…}를 씀 | . · 😀 | 반쪽 2개 | 😀 |
v | u에 문자 집합 빼기(--)·교집합(&&)을 더함 | [\p{L}--[a-z]] · aZ가 | 문법 오류 | Z, 가 |
y | 앞 일치가 끝난 자리에서 바로 이어질 때만 | \d · 12a3 (g와 함께) | 1, 2, 3 | 1, 2 |
d | 그룹마다 시작·끝 위치(indices)를 함께 냄 | 찾는 결과는 같습니다. 이 도구는 플래그와 상관없이 위치를 구해 일치 표에 씁니다. | ||
u와 v는 함께 켤 수 없습니다. 한쪽을 켜면 이 도구가 다른 쪽을 끄고 상태 줄에 알려 줍니다. v 플래그나 (?i:…) 같은 수정자처럼 최근에 생긴 문법은 오래된 브라우저에서 문법 오류가 날 수 있습니다.
캡처 그룹, 이름 그룹, 되참조
괄호 ( )로 감싼 부분은 일치 안에서 따로 저장되는 캡처 그룹이 됩니다. 여는 괄호 순서대로 1, 2, 3번이 붙고, (?<y>…)처럼 이름을 주면 번호와 이름을 함께 갖습니다. 묶기만 하고 저장할 필요가 없으면 (?:…)를 씁니다. 저장하지 않는 묶음은 번호를 차지하지 않아서 뒤 그룹의 번호가 바뀌지 않습니다.
패턴 안에서 앞 그룹이 잡은 글을 다시 찾으려면 되참조 \1이나 \k<이름>을 씁니다. (\w)\1은 같은 글자가 두 번 이어진 곳을 찾습니다. 그룹이 반복되면((\d)+) 마지막 반복에서 잡힌 값만 남는다는 점도 기억해 두세요. 일치 표에서 '—'로 보이는 칸은 그 일치에서 쓰이지 않은 그룹이고((a)|(b)에서 b가 맞을 때 1번 그룹), '빈 값'은 그룹이 빈 글자에 맞은 경우입니다.
바꿀 문자열에 쓰는 기호
바꾸기 탭의 결과는 자바스크립트 String.prototype.replace와 같은 규칙으로 만듭니다. 아래 표는 글 '주문 2026-10-22 출고'에 패턴 (\d{4})-(\d{2})-(\d{2})를 쓴 결과입니다.
| 기호 | 뜻 | 바꿀 문자열 | 결과 |
|---|---|---|---|
$1~$99 | 번호 그룹 | $3.$2.$1 | 주문 22.10.2026 출고 |
$<이름> | 이름 그룹(패턴에 이름이 있을 때) | $<m>월 $<d>일 | 주문 10월 22일 출고 |
$& | 일치한 글 전체 | [$&] | 주문 [2026-10-22] 출고 |
$` | 일치 앞의 글 전부 | ($`) | 주문 (주문 ) 출고 |
$' | 일치 뒤의 글 전부 | ($') | 주문 ( 출고) 출고 |
$$ | $ 글자 하나 | $$1 | 주문 $1 출고 |
\n | 줄바꿈이 아니라 글자 \ 와 n | $1\n$2 | 주문 2026\n10 출고 |
그룹 수보다 큰 번호($7)는 글자 그대로 남고, $0도 그룹이 아니라 글자로 남습니다. 줄바꿈을 넣고 싶으면 바꿀 문자열 칸에서 Enter로 실제 줄을 바꿉니다. 코드에서는 문자열 안에 "\n"을 쓰면 됩니다.
한글을 찾을 때
자바스크립트의 \w와 \b는 영문·숫자·밑줄만 '단어 글자'로 봅니다. u 플래그를 켜도 마찬가지라서 \w+로는 한글을 찾을 수 없고, \b한글\b도 한글 단어의 경계를 찾지 못합니다. [가-힣]은 유니코드 U+AC00부터 U+D7A3까지 완성형 음절 11,172자를 뜻하므로 'ㄱ', 'ㅏ' 같은 자모는 들어가지 않습니다.
| 패턴 | 찾는 것 | 설명 |
|---|---|---|
\w+ | abc | 한글은 하나도 잡지 않음 |
[가-힣]+ | 가, 힣, 한글 | 완성형 음절만 |
[ㄱ-ㅎㅏ-ㅣ가-힣]+ | 가, 힣, ㄱ, ㅏ, 한글 | 자음·모음 자모까지 |
\p{Script=Hangul}+ (u) | 가, 힣, ㄱ, ㅏ, 한글 | 유니코드 한글 문자 전체(옛한글 자모 포함) |
\b한글\b | 없음 | \b가 한글을 단어 글자로 보지 않음 |
한글 단어의 경계가 필요하면 전방·후방탐색으로 직접 적습니다. 예시의 '겹친 단어' 패턴 (?<![가-힣\w])([가-힣\w]+) \1(?![가-힣\w])처럼, 앞뒤에 한글·영문·숫자가 없을 때만 맞게 하면 됩니다.
줄마다 따로와 m 플래그의 차이
m 플래그는 글 전체를 한 번에 검사하면서 ^와 $가 줄의 시작과 끝에도 맞게 합니다. 그래서 일치가 줄을 넘어 이어질 수 있고(\s는 줄바꿈도 받음), 결과는 '몇 곳 일치'로만 나옵니다. 줄마다 따로는 줄을 하나씩 잘라 각 줄을 독립된 글로 검사합니다. 일치가 줄을 넘지 않고, 줄마다 통과(✓)·불통(✗)이 정해지며, 상태 줄에 '통과 3 / 6줄'처럼 나옵니다. 회원 가입 폼처럼 입력값 하나 전체를 검사할 패턴을 여러 예로 시험할 때는 줄마다 따로가 실제 쓰임과 같습니다. 바꾸기도 줄마다 한 뒤 다시 이어 붙입니다.
느린 패턴과 1초 제한
자바스크립트의 정규식 엔진은 맞는 길을 찾을 때까지 앞의 선택을 되돌려 다른 길을 시도합니다(백트래킹). 같은 글자를 여러 반복이 나눠 가질 수 있는 패턴은 맞지 않는 글을 만나면 나누는 경우의 수를 모두 시도합니다. Cloudflare 보고서는 문제 부분을 .*.*=.*로 줄여 설명합니다. 이 패턴은 x=x를 23단계 만에 맞히지만, x= 뒤에 x가 20개이면 555단계가 걸리고, = 없이 x만 20개인 글은 맞지 않는다고 판정하기까지 4,067단계가 걸립니다. 끝에 ; 하나를 붙인 .*.*=.*;는 x= 뒤에 x가 20개인 글에서 5,353단계를 거친 뒤 실패합니다. 반복 안에 반복이 있는 (a+)+$는 글이 한 글자 길어질 때마다 시도가 대략 두 배로 늘어납니다.
이 도구는 실행을 별도 작업 공간(Web Worker)에서 하고, 1초 안에 끝나지 않으면 작업을 끝내고 알려 줍니다. 화면은 멈추지 않습니다. 패턴 해부 줄의 주황 칸이 원인일 가능성이 큽니다. 고치는 방법은 대개 다음 세 가지입니다.
- 반복 안의 반복을 없앱니다.
(\w+\s?)+$대신\w+(?:\s\w+)*$처럼 반복마다 반드시 다른 글자(여기서는 공백)가 끼게 합니다. .*대신 멈출 글자를 뺀 집합을 씁니다..*.*=.*는[^=]*=.*로 바꾸면 같은 글을 찾으면서 되돌릴 길이 거의 없습니다.- 같은 글을 여러 방법으로 나눌 수 있는 선택지를 하나로 합칩니다.
(\d|\d\d)+$는 숫자 줄을 1자리·2자리로 나누는 모든 방법을 시도하지만,\d+$는 한 번에 끝납니다.
언어마다 다른 점
정규식 문법은 언어마다 조금씩 다릅니다. 이 도구의 결과는 자바스크립트 기준이므로, 다른 언어로 옮길 때는 아래 차이를 확인하세요. 표는 Node.js 26, Python 3.14, PHP 8.5(PCRE2 10.44)에서 직접 실행하고, Java는 Java 21 공식 문서로 확인했습니다.
| 항목 | JavaScript | Python re | Java | PHP preg_* |
|---|---|---|---|---|
| 이름 그룹 | (?<n>…) | (?P<n>…)만, (?<n>…)는 오류 | (?<n>…) | (?<n>…), (?P<n>…) |
| 바꿀 문자열의 그룹 | $1, $<n> | \1, \g<n> | $1, ${n} | $1, \1, ${1}(이름은 안 됨) |
\w가 한글을 잡나 | 아니요(u를 켜도) | 예(문자열 패턴 기본, re.ASCII면 아니요) | 아니요(UNICODE_CHARACTER_CLASS면 예) | 아니요(/u면 예) |
소유 수량자 a++, 원자 그룹 (?>…) | 없음(문법 오류) | 있음(3.11부터) | 있음 | 있음 |
| 플래그 쓰는 곳 | /…/gi 뒤 글자 | re.I 같은 인자, 모두 찾기는 findall·sub | Pattern.CASE_INSENSITIVE 같은 인자 | 구분자 뒤 글자 /…/iu |
후방탐색((?<=…)) 안에 쓸 수 있는 길이도 다릅니다. 자바스크립트는 (?<=a+)처럼 길이가 정해지지 않은 패턴도 받지만, Python은 고정 길이만 받고, PHP는 PCRE2 10.43부터 길이 상한이 있는 패턴((?<=a{1,3}), 기본 최대 255자)까지 받습니다. Python의 \d는 전각 숫자 '12'도 숫자로 보는 반면, 자바스크립트의 \d는 0~9만 봅니다.
자주 틀리는 경우
- 문자열로 만들 때 역슬래시를 한 번만 씀: 자바스크립트 문자열
"\d+"는d+가 됩니다.new RegExp("\\d+")처럼 두 번 써야 합니다. 코드 탭의 '문자열로 만들 때' 줄은 이 처리를 해 둔 모양입니다. - 마침표를 그냥 씀:
1.5는 '125'에도 맞습니다. 마침표 글자는1\.5로 씁니다. - g 플래그 정규식으로
test()를 여러 번 부름: 정규식이 마지막 위치(lastIndex)를 기억해서, 같은 글에 대한 결과가 true, false, true로 번갈아 나옵니다. 검사만 할 때는 g를 빼는 편이 안전합니다. - 탐욕스러운
.*:<.+>는 '<b>x</b>' 전체를 한 번에 잡습니다. 태그 하나씩 잡으려면<.+?>나<[^>]+>를 씁니다. - 검증 패턴을 여러 줄 글에 그대로 댐:
^…$는 m 플래그 없이 글 전체를 한 덩어리로 보므로 여러 줄이면 0곳이 나옵니다. 예를 여러 개 시험할 때는 줄마다 따로를 켭니다. - 이메일을 정규식 하나로 완벽하게 검사하려 함: 표준이 허용하는 주소는 매우 다양해서 간단한 패턴은 일부를 놓치거나 더 받습니다. 예시의 이메일 패턴은 모양을 대략 거르는 용도이고, 실제 확인은 메일 인증으로 하는 것이 일반적입니다.
한계
- 결과는 지금 쓰는 브라우저의 자바스크립트 정규식 엔진 기준입니다. Python·Java·PHP·편집기의 정규식은 위 표처럼 문법과 결과가 다를 수 있습니다.
- 패턴은 1,000자, 테스트할 글은 50,000자, 바꿀 문자열은 2,000자, 바꾼 결과는 200,000자까지입니다. 일치 표와 글 위 칠은 처음 1,000곳까지 보이고, 일치 수와 바꾼 결과에는 전체가 들어갑니다.
- 실행이 1초를 넘으면 멈춥니다. 느린 기기에서는 같은 패턴도 더 오래 걸릴 수 있습니다.
- 패턴 해부 줄의 '느려질 수 있음' 표시는 흔한 모양만 찾는 경고입니다. 표시가 없다고 해서 모든 글에서 빠르다는 보장은 아닙니다.
- 일치 표의 '줄:열'은 자바스크립트 문자열 위치(UTF-16) 기준이어서 이모지 하나가 두 칸으로 셉니다.
- 입력한 패턴과 글은 브라우저 안에서만 처리하고 서버로 보내지 않습니다. 주소나 저장소에도 남기지 않으므로 새로 고치면 예시로 돌아갑니다.
기준: 문법과 치환 규칙은 ECMAScript 명세와 MDN 문서, 다른 언어는 Python·Java·PHP 공식 문서와 PCRE2 변경 기록을 2026년 10월 22일에 확인했습니다. 표의 예는 Node.js 26(V8), Python 3.14, PHP 8.5에서 실행해 같은 결과를 확인했습니다.
출처
- 01ECMAScript: RegExp (Regular Expression) Objects자바스크립트 정규식 문법과 실행 규칙
- 02ECMAScript: GetSubstitution$1, $<이름>, $&, $`, $', $$ 처리 순서
- 03MDN: Regular expressions플래그, 수정자 (?i:…), v 플래그, 이름 그룹
- 04MDN: String.prototype.replace()바꿀 문자열의 특수 기호
- 05MDN: Character class escape\d, \w, \s가 받는 글자
- 06Cloudflare: Details of the Cloudflare outage on July 2, 2019WAF 정규식의 백트래킹으로 27분 장애, .*.*=.* 단계 수
- 07Python: re — Regular expression operations(?P<이름>…), \g<이름>, 고정 길이 후방탐색, 3.11 소유 수량자
- 08Java 21: Pattern\w = [a-zA-Z_0-9](UNICODE_CHARACTER_CLASS 없을 때), 소유 수량자
- 09PHP: preg_replace바꿀 문자열의 $n, \n, ${n}
- 10PCRE2 ChangeLog10.43: 길이 상한이 있는 가변 길이 후방탐색(기본 255자)
- 11Unicode: Hangul Syllables (AC00–D7AF)완성형 한글 음절 영역
자주 묻는 질문
패턴에 /와 플래그까지 붙여 넣어도 되나요?
패턴 칸에는 슬래시 안쪽만 넣고 플래그는 오른쪽 글자 단추로 켭니다. /abc/gi처럼 리터럴째 붙여 넣으면 이 도구가 패턴 abc와 플래그 g, i로 나눠 넣습니다. 손으로 칠 때 슬래시를 넣으면 슬래시도 찾을 글자로 읽힙니다.
여러 군데가 맞는데 한 곳만 칠해지는 이유는 무엇인가요?
g 플래그가 꺼져 있으면 첫 일치에서 멈춥니다. 이때 상태 줄에 'g를 켜면 몇 곳'인지 함께 보여 주므로, g 단추를 눌러 모두 찾으면 됩니다.
한글이 \w에 잡히지 않는 이유는 무엇인가요?
자바스크립트의 \w는 영문·숫자·밑줄만 받고, u 플래그를 켜도 같습니다. 한글 음절은 [가-힣], 자모까지는 [ㄱ-ㅎㅏ-ㅣ가-힣], 유니코드 한글 전체는 u 플래그와 \p{Script=Hangul}로 찾습니다.
m 플래그와 줄마다 따로는 어떻게 다른가요?
m 플래그는 글 전체를 한 번에 검사하면서 ^와 $가 줄마다 맞게 합니다. 줄마다 따로는 줄을 하나씩 독립된 글로 검사해 줄마다 통과·불통을 표시합니다. 입력값 하나를 검사하는 패턴을 여러 예로 시험할 때는 줄마다 따로가 맞습니다.
바꿀 문자열에 그룹 값은 어떻게 넣나요?
번호 그룹은 $1, $2, 이름 그룹은 $<이름>, 일치 전체는 $&로 넣습니다. 바꾸기 탭의 기호 단추를 누르면 커서 자리에 들어갑니다. \n은 줄바꿈이 아니라 글자 그대로 들어가므로 줄을 바꾸려면 Enter를 누르세요.
1초 제한에 걸려 멈추면 패턴이 틀린 건가요?
문법은 맞아도 백트래킹이 폭증하는 모양일 수 있습니다. (a+)+처럼 반복 안의 반복이나 .*.*처럼 같은 반복이 연달아 있으면 맞지 않는 긴 글에서 시도가 급격히 늘어납니다. 패턴 해부 줄의 주황 칸을 보고 반복을 합치거나 .* 대신 [^=]* 같은 좁은 집합을 쓰세요.
Python이나 Java, PHP에서도 결과가 같나요?
기본 문법은 비슷하지만 차이가 있습니다. Python은 이름 그룹을 (?P<이름>…)로 쓰고 \w가 한글도 받으며, PHP는 /u를 붙이면 \w가 한글을 받습니다. 바꿀 문자열의 그룹 표기도 \1, ${이름}처럼 다릅니다. 본문의 '언어마다 다른 점' 표를 확인하세요.
입력한 글이 서버로 전송되나요?
보내지 않습니다. 패턴과 글은 브라우저 안의 작업 공간(Web Worker)에서만 실행하고, 주소나 저장소에도 남기지 않습니다. 새로 고치면 첫 예시로 돌아갑니다.