정규 표현식은 무작위 노이즈처럼 보인다는 평판이 있습니다. ^[\w.-]+@[\w-]+\.\w{2,}$ 같은 패턴은 고양이가 키보드 위를 걸어간 것처럼 보일 수 있습니다. 하지만 이 암호 같은 구문 뒤에는 놀랍도록 우아한 아이디어가 있습니다: 텍스트의 패턴을 간결하게 기술하는 언어입니다.
폼 입력 유효성 검사, 로그 파일 검색, 데이터 정리, 코드베이스 전체의 찾기 및 바꾸기 등 regex는 개발자 도구 상자에서 가장 다용도적인 도구 중 하나입니다. 모든 세세한 기능을 외울 필요는 없습니다. 소수의 구성 요소로 실용적인 사용 사례의 대부분을 커버할 수 있습니다.
정규 표현식이란
정규 표현식(regex 또는 regexp)은 문자열의 집합을 기술하는 패턴입니다. 프로그래밍 언어, 텍스트 편집기, 명령줄 도구의 검색 엔진에 제공하면 일치하는 모든 문자열을 찾습니다.
향상된 검색 쿼리라고 생각하세요:
- 일반 검색: 정확한 단어 "error"를 찾기
- Regex 검색: IP 주소, 날짜, 이메일 주소, 또는 기술할 수 있는 어떤 구조든 찾기
정규 표현식은 수학자 스티븐 클리니가 1956년에 발명했으며, 1960년대에 Unix 텍스트 편집기를 통해 컴퓨팅에 도입되었습니다. 오늘날 거의 모든 프로그래밍 언어와 텍스트 편집기에서 지원됩니다.
구성 요소
리터럴 문자
가장 간단한 regex는 일반 텍스트입니다. 패턴 hello는 나타나는 곳 어디든 "hello"와 일치합니다. 특별한 것은 없습니다.
점(.) — 임의의 한 문자
점은 줄바꿈을 제외한 임의의 한 문자와 일치합니다.
h.t는 "hat", "hit", "hot", "h3t", 심지어 "h t"와도 일치합니다
문자 클래스([])
대괄호는 한 위치에서 허용되는 문자의 집합을 정의합니다.
[aeiou]— 임의의 모음[0-9]— 임의의 숫자[A-Za-z]— 임의의 영문자[^0-9]— 숫자가 아닌 임의의 문자(대괄호 안의^는 "아닌"을 의미)
약식 클래스
| 약식 | 의미 | 동등 |
|---|---|---|
\d |
임의의 숫자 | [0-9] |
\w |
단어 문자 | [A-Za-z0-9_] |
\s |
공백 문자 | [ \t\n\r] |
\D |
숫자 아닌 문자 | [^0-9] |
\W |
단어 문자 아닌 문자 | [^A-Za-z0-9_] |
\S |
공백 아닌 문자 | [^ \t\n\r] |
수량자 — 몇 개
수량자는 앞의 요소가 몇 번 나타나야 하는지를 제어합니다.
| 기호 | 의미 | 예시 | 일치 |
|---|---|---|---|
* |
0번 이상 | ab*c |
"ac", "abc", "abbc" |
+ |
1번 이상 | ab+c |
"abc", "abbc" ("ac" 불가) |
? |
0번 또는 1번 | colou?r |
"color"과 "colour" |
{3} |
정확히 3번 | \d{3} |
"123", "456" |
{2,4} |
2~4번 | \d{2,4} |
"12", "123", "1234" |
앵커 — 위치
^— 문자열의 시작(m플래그에서는 각 줄의 시작)$— 문자열의 끝(또는 각 줄의 끝)\b— 단어 경계
패턴 ^\d{4}$는 "2026"처럼 정확히 네 자리 숫자인 문자열과 일치하지만, "abc2026"이나 "2026xyz"와는 일치하지 않습니다.
그룹과 교대
(abc)— "abc"를 그룹으로 캡처a|b— "a" 또는 "b"와 일치(cat|dog)— "cat" 또는 "dog"과 일치
그룹을 사용하면 시퀀스에 수량자를 적용할 수도 있습니다: (ha)+는 "ha", "haha", "hahaha"와 일치합니다.
자주 사용하는 실용적 패턴
이메일 유효성 검사(기본)
^[\w.-]+@[\w-]+\.\w{2,}$
user@example.com, first.last@company.co.uk(부분적)과 일치하며, @이나 도메인이 없는 문자열을 거부합니다.
중요: 정규 표현식으로 이메일 주소를 완벽하게 검증하는 것은 매우 어렵기로 유명합니다. RFC 5322의 전체 사양은 극도로 복잡합니다. 프로덕션 시스템에서는 기본적인 regex로 형식 검사를 하고, 확인 이메일을 보내 주소를 검증하세요.
전화번호 일치
\+?\d{1,3}[-.\s]?\(?\d{1,4}\)?[-.\s]?\d{3,4}[-.\s]?\d{3,4}
+1 555 123 4567, 555-123-4567, (555) 123-4567 같은 형식을 처리합니다.
URL 일치
https?://[\w.-]+(/[\w./?&=-]*)?
https://example.com, http://example.com/path?q=hello와 일치합니다.
날짜 일치(YYYY-MM-DD)
\d{4}-\d{2}-\d{2}
2026-03-29, 1999-12-31과 일치합니다. 참고: 이것은 형식만 검사하며 유효성은 확인하지 않습니다 — 9999-99-99와도 일치합니다.
동작을 바꾸는 플래그
대부분의 regex 엔진은 패턴 적용 방법을 변경하는 플래그를 지원합니다:
| 플래그 | 이름 | 효과 |
|---|---|---|
g |
전역 | 첫 일치만이 아닌, 모든 일치를 검색 |
i |
대소문자 무시 | hello가 "Hello", "HELLO" 등과 일치 |
m |
멀티라인 | ^과 $가 각 줄의 시작/끝에 일치 |
s |
Dotall | .이 줄바꿈 문자에도 일치 |
JavaScript에서 플래그는 닫는 슬래시 뒤에 추가합니다: /hello/gi. Python에서는 인수로 전달합니다: re.findall(r"hello", text, re.IGNORECASE).
regex가 과한 경우
regex는 강력하지만 항상 올바른 도구는 아닙니다:
- HTML이나 XML 파싱. 적절한 DOM 파서를 사용하세요. regex는 중첩된 태그를 신뢰할 수 있게 처리할 수 없습니다.
- JSON 파싱.
JSON.parse()또는 동등한 것을 사용하세요. regex는 에지 케이스에서 깨집니다. - 복잡한 유효성 검사. 패턴이 여러 줄에 걸쳐 있고 읽는 데 5분이 걸린다면, 절차적 유효성 검사 코드 작성을 고려하세요.
- 간단한 문자열 작업.
startsWith(),includes(),split()으로 충분하다면, 일반 문자열 메서드가 더 명확하고 빠릅니다.
흔한 함정
- 특수 문자 이스케이프 잊음. 점
.은 임의의 문자와 일치합니다. 리터럴 점에 일치시키려면\.을 사용하세요.(,),[,],+,*,?,{,},^,$,|,\도 마찬가지입니다. - 탐욕적 vs 게으른 매칭. 기본적으로
.*은 탐욕적입니다 — 가능한 많이 일치합니다.?를 추가하면 게으르게 됩니다:.*?는 가능한 적게 일치합니다. 이것은 구분자 사이의 콘텐츠를 추출할 때 중요합니다. - 재앙적 백트래킹.
(a+)+같은 중첩된 수량자는 특정 입력에 대해 엔진이 지수적인 수의 경로를 시도하여 프로그램이 멈출 수 있습니다. 겹치는 패턴에서의 중첩된 반복을 피하세요. - 앵커 빠뜨리기.
^과$없이는 패턴이 부분 문자열과 일치합니다.\d{3}은 "abc12345" 안의 "123"과 일치합니다. 정확한 일치가 필요하면^\d{3}$을 사용하세요.
더 알아보기
regex를 배우는 가장 좋은 방법은 실험하는 것입니다. 패턴을 입력하고, 테스트 텍스트를 붙여넣고, 무엇이 강조되는지 확인하세요. 각 부분이 어떻게 작동하는지 이해할 때까지 조정하고 반복하세요.
- Regex 패턴 테스트 방법 — 예제가 있는 대화형 튜토리얼
- Regex 테스터 — 패턴과 테스트 데이터를 붙여넣고 일치 항목을 실시간으로 강조 표시
