정규식은 텍스트 검색, 유효성 검사, 변환이 필요할 때마다 활용도가 높은 기술입니다. 이 치트시트는 가장 많이 쓰이는 패턴을 즉시 테스트할 수 있는 예제와 함께 정리합니다.

실시간 정규식 테스터 열기 →

문자 클래스

패턴매칭 대상
.줄바꿈을 제외한 모든 문자
\d숫자 [0-9]
\D숫자가 아닌 문자
\w단어 문자 [a-zA-Z0-9_]
\W단어 문자가 아닌 것
\s공백 (스페이스, 탭, 줄바꿈)
\S공백이 아닌 것
[abc]a, b, c 중 하나
[^abc]a, b, c가 아닌 것
[a-z]소문자 a부터 z
[A-Z]대문자 A부터 Z
[0-9]숫자 0부터 9

앵커

패턴매칭 대상
^문자열 시작 (멀티라인 모드에서는 줄 시작)
$문자열 끝 (멀티라인 모드에서는 줄 끝)
\b단어 경계
\B단어 경계가 아닌 것
/^\d{5}$/    → 정확히 5자리 숫자만 매칭 (우편번호)
/\bword\b/   → "word"는 매칭, "password"는 미매칭

수량자

패턴의미
*0번 이상
+1번 이상
?0 또는 1번 (선택적)
{n}정확히 n번
{n,}n번 이상
{n,m}n번 이상 m번 이하

탐욕적(greedy) vs 게으른(lazy): 기본적으로 수량자는 탐욕적(가능한 많이 매칭)입니다. ?를 추가하면 게으른 방식이 됩니다:

<.+>    → 탐욕적: <b>bold</b> 전체를 하나로 매칭
<.+?>   → 게으른: <b>와 </b>를 별도로 매칭

그룹과 선택

패턴의미
(abc)캡처 그룹
(?:abc)비캡처 그룹
a|b선택: a 또는 b
\1첫 번째 그룹에 대한 역참조
// 날짜 문자열에서 연, 월, 일 추출
const match = '2026-04-07'.match(/(\d{4})-(\d{2})-(\d{2})/);
// match[1] = '2026', match[2] = '04', match[3] = '07'

룩어헤드와 룩비하인드

패턴의미
(?=abc)긍정 룩어헤드 — abc 앞 위치
(?!abc)부정 룩어헤드 — abc가 없는 앞 위치
(?<=abc)긍정 룩비하인드 — abc 뒤 위치
(?<!abc)부정 룩비하인드 — abc가 없는 뒤 위치
/\d+(?= 원)/     → " 원" 앞의 숫자만 매칭
/(?<=\$)\d+/     → "$" 뒤의 숫자만 매칭

룩비하인드는 JavaScript에서 ES2018 이상이 필요합니다.

플래그

플래그효과
i대소문자 무시
g전역 — 모든 매칭 찾기
m멀티라인 — ^$가 줄 경계 매칭
sDotall — .이 줄바꿈도 매칭
u유니코드 모드
/hello/i.test('Hello World')  // true
'abc abc'.match(/abc/g)       // ['abc', 'abc']

자주 쓰는 패턴

이메일 (기본)

/^[^\s@]+@[^\s@]+\.[^\s@]+$/

URL

/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/

IPv4 주소

/^(\d{1,3}\.){3}\d{1,3}$/

16진수 색상

/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/

한국 휴대폰 번호

/^01[016789]-?\d{3,4}-?\d{4}$/

URL 슬러그

/^[a-z0-9]+(?:-[a-z0-9]+)*$/

Semver

/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*))?(?:\+([\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*))?$/

코드에서 정규식 사용하기

JavaScript

// 문자열이 패턴과 일치하는지 테스트
/^\d+$/.test('123')       // true
/^\d+$/.test('12a')       // false

// 첫 번째 매칭 찾기
'hello world'.match(/\w+/)    // ['hello']

// 모든 매칭 찾기
'hello world'.match(/\w+/g)   // ['hello', 'world']

// 교체
'foo bar'.replace(/\b\w/g, c => c.toUpperCase())  // 'Foo Bar'

// 분할
'one, two,three'.split(/,\s*/)  // ['one', 'two', 'three']

Python

import re

# 테스트
bool(re.match(r'^\d+$', '123'))        # True

# 첫 번째 찾기
re.search(r'\d+', 'abc123def')         # 매칭 객체
re.search(r'\d+', 'abc123def').group() # '123'

# 모두 찾기
re.findall(r'\d+', 'a1 b22 c333')      # ['1', '22', '333']

# 교체
re.sub(r'\s+', '-', 'hello world')     # 'hello-world'

실시간으로 정규식 테스트하기

패턴을 작성할 때 배포 전에 반드시 테스트하세요 — 엣지 케이스를 놓치기 쉽습니다.

ZeroTool 정규식 테스터 →

  • 패턴과 테스트 문자열을 붙여넣기
  • 실시간으로 모든 매칭 하이라이트
  • 플래그 지원: g, i, m, s
  • 캡처 그룹 결과 표시

디버깅 팁

  1. 단순하게 시작 — 패턴을 조각씩 구성하기
  2. Python에서 raw 문자열 사용r'\d+'는 이중 이스케이프를 피함
  3. 특수문자 이스케이프., *, +, ?, (, ), [, ], {, }, ^, $, |, \는 리터럴로 쓸 때 이스케이프 필요
  4. 앵커 의식적 사용/\d+/는 어디서든 숫자 매칭; /^\d+$/는 전체 문자열이 숫자여야 함
  5. 경계 케이스로 테스트 — 빈 문자열, 전체 매칭, 매칭 없음, 겹치는 패턴

정규식은 강력하지만 빠르게 유지보수 불가 상태가 됩니다. 패턴이 ~60자를 넘으면 명명된 서브패턴으로 분리하거나 파서 라이브러리 사용을 고려하세요.

ZeroTool 정규식 테스터에서 패턴을 바로 테스트하기 →