정규표현식(Regex) 완전 가이드: 기초 문법부터 실전 패턴 30선까지
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
정규표현식(Regular Expression, Regex)은 문자열에서 특정 패턴을 검색·추출·치환하는 강력한 도구입니다.
처음 보면 암호처럼 느껴지지만, 몇 가지 규칙만 알면 100줄 코드를 1줄로 줄일 수 있습니다.
이메일 유효성 검사, URL 파싱, 로그 분석, 데이터 정제 등 실무 곳곳에서 매일 마주칩니다.
이 글은 정규식 기본 문법, 한국 특화 패턴(휴대폰·주민등록번호·사업자등록번호), 자주 쓰는 30가지 패턴,
JavaScript/Python 사용법, ReDoS 보안 위험까지 한 번에 정리합니다.
정규표현식이란?#
정규표현식은 문자열의 패턴을 표현하는 작은 언어입니다.
1950년대 수학자 Stephen Kleene이 정의한 이론에서 출발해,
Unix grep(1973)·Perl(1987)을 거쳐 현대 모든 프로그래밍 언어의 표준 기능이 되었습니다.
대부분의 언어는 PCRE(Perl Compatible Regular Expressions) 또는 ECMA-262(JavaScript) 방언을 사용합니다.
문법은 거의 같지만 일부 기능(lookbehind, named groups 등)이 다를 수 있습니다.
기본 문법 요소#
메타문자(특별한 의미를 가진 기호)#
| 기호 | 의미 | 예시 |
|---|---|---|
. | 임의의 한 문자 | a.c → "abc", "a1c" |
* | 0회 이상 반복 | a* → "", "a", "aaa" |
+ | 1회 이상 반복 | a+ → "a", "aaa" |
? | 0 또는 1회 | colou?r → "color", "colour" |
^ | 문자열 시작 | ^Hello → "Hello"로 시작 |
$ | 문자열 끝 | end$ → "end"로 끝 |
[] | 문자 집합 | [abc] → a, b, c 중 하나 |
[^] | 제외 문자 집합 | [^0-9] → 숫자가 아닌 문자 |
{n} | 정확히 n회 | \d{3} → 3자리 숫자 |
{n,} | n회 이상 | \d{2,} → 2자리 이상 |
{n,m} | n에서 m회 | \d{2,4} → 2–4자리 숫자 |
\d | 숫자 [0-9] | \d+ → 숫자 1개 이상 |
\D | 숫자 아닌 문자 | \D+ |
\w | 단어 문자 [a-zA-Z0-9_] | \w+ → 단어 |
\W | 단어 아닌 문자 | \W+ |
\s | 공백 문자 | \s+ → 공백 |
\S | 공백 아닌 문자 | \S+ |
| | OR 연산 | cat|dog → "cat" 또는 "dog" |
() | 캡처 그룹 | (ab)+ → "ab", "abab" |
(?:) | 비캡처 그룹 | (?:ab)+ → 캡처하지 않음 |
\ | 이스케이프 | \., \$ → 메타문자 자체 |
앵커와 경계#
| 기호 | 의미 |
|---|---|
\b | 단어 경계 |
\B | 단어 경계 아님 |
\A | 문자열 절대 시작 |
\Z | 문자열 절대 끝 |
룩어라운드(Lookaround)#
매칭하지만 결과에 포함하지 않는 패턴 검사입니다.
| 기호 | 의미 |
|---|---|
(?=...) | 긍정 룩어헤드: 뒤에 있어야 함 |
(?!...) | 부정 룩어헤드: 뒤에 없어야 함 |
(?<=...) | 긍정 룩비하인드: 앞에 있어야 함 |
(?<!...) | 부정 룩비하인드: 앞에 없어야 함 |
비밀번호 강도 검사처럼 여러 조건을 동시에 확인할 때 유용합니다.
자주 쓰는 패턴 30선#
유효성 검사(10개)#
1. 이메일 주소
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
test@example.com, user.name+tag@domain.co.kr 형식 검증.
2. 한국 휴대폰 번호
^01[016789]-?\d{3,4}-?\d{4}$
010-1234-5678, 01012345678 모두 허용.
3. 한국 일반 전화번호
^0[2-9]\d{1,2}-?\d{3,4}-?\d{4}$
02-123-4567, 031-1234-5678 등.
4. 한국 주민등록번호
^\d{6}-?[1-4]\d{6}$
뒷자리 첫 숫자가 1–4(내국인)인 경우. 주민등록번호는 절대 평문 저장 금지(개인정보보호법).
5. 한국 사업자등록번호
^\d{3}-?\d{2}-?\d{5}$
123-45-67890 형식.
6. URL
^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}(\/[-a-zA-Z0-9()@:%_+.~#?&\/=]*)?$
7. IPv4 주소
^(\d{1,3}\.){3}\d{1,3}$
엄격한 검증은 각 옥텟이 0–255 범위 확인 필요.
8. IPv6 주소
^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$
9. 한국 우편번호
^\d{5}$
2015년부터 5자리 사용.
10. 카드번호(공백·하이픈 포함)
^(\d{4}[\s-]?){3}\d{4}$
PCI DSS는 평문 저장을 엄격히 제한합니다.
문자열 처리(10개)#
11. 공백만 있는 줄
^\s*$
12. HTML 태그 제거
<[^>]+>
13. 연속된 공백을 하나로
\s{2,}
14. 양쪽 공백 제거(trim)
^\s+|\s+$
15. 숫자만 추출
\d+
16. 한글만 추출
[가-힣]+
17. 영문자만 추출
[a-zA-Z]+
18. 특수문자 제거
[^a-zA-Z0-9가-힣\s]
19. 줄바꿈을 공백으로
\n+
20. 큰따옴표 안 텍스트
"([^"]*)"
날짜·시간(5개)#
21. YYYY-MM-DD 형식
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
22. HH:MM:SS 형식
^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$
23. ISO 8601(2026-05-04T12:34:56Z)
^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})$
24. 한국식 날짜(2026년 5월 4일)
^\d{4}년\s*\d{1,2}월\s*\d{1,2}일$
25. 12시간 형식 시간
^(0?[1-9]|1[0-2]):[0-5]\d\s?(AM|PM|am|pm|오전|오후)$
비밀번호·보안(5개)#
26. 최소 8자, 대소문자·숫자·특수문자 모두 포함
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$
27. 최소 12자, 대소문자·숫자
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{12,}$
28. 한국식 사용자 ID(영문/숫자/언더스코어 4–20자)
^[a-zA-Z0-9_]{4,20}$
29. JWT 토큰
^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+$
30. UUID v4
^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
언어별 사용법#
JavaScript#
// 문자열 검색
const regex = /\d+/g;
const str = "나는 25살이고 키가 175cm입니다";
const numbers = str.match(regex);
// → ["25", "175"]
// 문자열 치환
const phone = "010-1234-5678";
const normalized = phone.replace(/-/g, "");
// → "01012345678"
// 유효성 검사
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
emailRegex.test("user@example.com"); // → true
// 그룹 추출
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
const match = "2026-05-04".match(dateRegex);
// match[1] → "2026", match[2] → "05", match[3] → "04"
// Named groups
const namedRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const m = "2026-05-04".match(namedRegex);
// m.groups.year → "2026"
// matchAll(g 플래그 필수)
const allRegex = /\d+/g;
[..."10 20 30".matchAll(allRegex)]; // 각 매칭 객체 배열
Python#
import re
# 검색
re.search(r"\d+", "I am 25 years old") # match object
# 치환
re.sub(r"-", "", "010-1234-5678") # "01012345678"
# 모든 매칭
re.findall(r"\d+", "1 hello 22 world 333") # ["1", "22", "333"]
# 컴파일(반복 사용 시 성능)
pattern = re.compile(r"\d+")
pattern.findall("text 42") # ["42"]
Shell(grep, sed)#
# 패턴 검색
grep -E "^[0-9]+$" file.txt # 숫자만 있는 줄
# 치환
sed -E "s/[0-9]+/#/g" file.txt # 숫자를 #로 치환
# Perl 호환 정규식(PCRE)
grep -P "\d+" file.txt
플래그(Flags)#
| 플래그 | 의미 |
|---|---|
g | 전체 매칭(global) |
i | 대소문자 무시(insensitive) |
m | 멀티라인: ^, $가 각 줄 시작·끝 |
s | dotAll: .이 줄바꿈 포함 |
u | 유니코드 |
y | sticky: lastIndex부터 매칭 |
"Hello".match(/hello/i); // 매칭 (대소문자 무시)
ReDoS: 정규식 보안 위험#
악의적 입력으로 정규식 엔진이 무한 루프에 빠지는 취약점입니다(Regular Expression Denial of Service).
위험 패턴#
(a+)+ # 중첩 수량자 — 위험
(.*)* # 같은 위험
(a|a)+ # OR 안에 동일 패턴 — 위험
안전한 대안#
a+ # 단순 수량자
[^x]+ # 부정 문자 클래스
JavaScript의 String.match()는 catastrophic backtracking에 취약합니다.
입력 길이를 제한하거나, RE2 같은 선형 시간 보장 엔진(Go·Rust)을 사용합니다.
본 사이트의 정규식 테스터는 ReDoS 의심 패턴을 자동 차단합니다.
흔한 실수와 해결법#
1. . 메타문자 이스케이프 누락#
잘못된 예: example.com
정상: example\.com
.은 모든 문자에 매칭되므로 도메인 검증 시 반드시 이스케이프합니다.
2. ?와 lazy/greedy 혼동#
greedy: <.+> → "<a><b>" 전체 매칭
lazy: <.+?> → "<a>", "<b>" 각각 매칭
HTML 태그·JSON 키 추출에서 자주 헷갈립니다.
3. 한글 매칭#
잘못된 예: [a-zA-Z]+ (한글 매칭 안 됨)
정상: [가-힣a-zA-Z]+
[가-힣]은 한글 음절 11,172자를 포함합니다. 한글 자모(ㄱ, ㅏ)도 포함하려면 [가-힣ㄱ-ㅎㅏ-ㅣ].
4. 캡처 그룹 vs 비캡처 그룹#
캡처: /(\d+)/ → match[1] 사용 가능
비캡처: /(?:\d+)/ → 그룹화만 하고 캡처 안 함 (성능 약간 빠름)
5. 너무 복잡한 정규식#
이메일 RFC 5322 완전 준수 정규식은 6,000자가 넘습니다.
90% 케이스를 잡는 단순 패턴을 쓰고, 정밀 검증은 인증 메일 발송으로 위임하는 것이 일반적입니다.
자주 묻는 질문#
Q. 정규식과 와일드카드(*, ?)의 차이는?
A. 와일드카드는 파일명 매칭(*.txt)에서 쓰이는 단순 패턴이고, 정규식은 훨씬 표현력 있는 패턴 언어입니다.
와일드카드 *는 정규식 .*에 해당합니다.
Q. 정규식 학습 순서를 추천한다면?
A. ① 기본 메타문자(., *, +, ?, []) → ② 앵커(^, $) → ③ 그룹과 캡처(()) → ④ 룩어라운드 → ⑤ 백레퍼런스 순서로 학습합니다.
Q. 정규식 성능이 느린 이유는?
A. 백트래킹(backtracking) 때문입니다.
모호한 패턴((a+)+)은 매칭 후보가 폭발적으로 늘어 시간 복잡도가 지수적으로 증가합니다.
단순 패턴, 부정 문자 클래스, 비캡처 그룹을 활용해 최적화합니다.
Q. 한국에서 자주 쓰는 정규식은?
A. 휴대폰 번호, 주민등록번호 일부 검증, 사업자등록번호, 카드번호, 은행 계좌번호, 한글만 추출, 한국 우편번호 등이 대표적입니다.
Q. 정규식 테스트는 어디서 하나요?
A. 정규식 테스터에서 패턴과 테스트 문자열을 입력하면 매칭 부분을 실시간 하이라이팅합니다.
30개 자주 쓰는 패턴 라이브러리, 치환 미리보기, URL 공유 기능을 무료로 제공합니다.
정규식 테스터 활용#
정규식 테스터에서 패턴과 플래그를 설정하면
실시간 매칭 하이라이팅, 그룹 추출, 치환 미리보기, CSV 다운로드까지 모두 처리합니다.
개발 도구가 더 필요하다면
JSON 포맷터 활용 가이드, Base64 인코딩 완전 가이드,
Unix 타임스탬프 완벽 가이드도 함께 참고할 수 있습니다.