정규 표현식: 개발자를 위한 실용 가이드
· 12분 읽기
목차
정규 표현식(regex)은 개발자 도구 상자에서 가장 강력한 도구 중 하나입니다. 패턴 설명을 사용하여 텍스트를 검색, 일치, 조작하는 간결하고 유연한 방법을 제공합니다. 사용자 입력 검증, 로그 파일 파싱, API에서 데이터 추출, 복잡한 찾기-바꾸기 작업 수행 등 효율적인 개발을 위해 정규식 지식은 필수적입니다.
이 종합 가이드는 기초부터 고급 패턴까지 실용적이고 실제적인 예제와 함께 안내합니다. 마지막에는 구문뿐만 아니라 프로젝트에서 정규식을 효과적으로 적용하는 시기와 방법을 이해하게 될 것입니다.
정규식 기초
핵심적으로 정규 표현식은 검색 패턴을 정의하는 문자 시퀀스입니다. 텍스트 패턴을 설명하는 미니 언어로 생각하면 됩니다. 모든 정규식 패턴의 기초를 형성하는 필수 구성 요소부터 시작하겠습니다.
리터럴 문자
가장 간단한 정규식은 리터럴 문자열입니다. hello 패턴은 입력에서 정확히 "hello" 텍스트와 일치합니다. 대부분의 문자는 그 자체로 리터럴하게 일치하므로 기본 검색이 간단합니다.
그러나 특정 문자는 정규식에서 특별한 의미를 가지며 메타문자라고 합니다. 이들을 리터럴하게 일치시키려면 백슬래시로 이스케이프해야 합니다:
. ^ $ * + ? { } [ ] \ | ( )
예를 들어, 리터럴 마침표를 일치시키려면 . 대신 \.를 사용합니다. 달러 기호를 일치시키려면 \$를 사용합니다.
앵커
앵커는 문자를 일치시키지 않고 텍스트의 위치를 일치시킵니다. 정확한 패턴 일치에 중요합니다:
^— 줄 또는 문자열의 시작과 일치$— 줄 또는 문자열의 끝과 일치\b— 단어 경계 (단어 문자와 비단어 문자 사이)\B— 비단어 경계 (\b의 반대)\A— 문자열의 시작 (일부 버전에서 멀티라인 모드에서^와 다름)\Z— 문자열의 끝 (일부 버전에서 멀티라인 모드에서$와 다름)
예제: ^Hello$ 패턴은 앞뒤에 다른 텍스트 없이 정확히 "Hello"만 포함하는 줄과 일치합니다.
예제: \bcat\b 패턴은 전체 단어로서 "cat"과 일치하지만 "category"나 "concatenate"의 "cat"과는 일치하지 않습니다.
전문가 팁: 부분 일치를 방지하려면 앵커를 사용하세요. 이메일 주소나 전화번호를 검증할 때는 항상 ^와 $로 패턴을 고정하여 문자열의 일부가 아닌 전체 문자열이 패턴과 일치하도록 하세요.
문자 클래스와 수량자
문자 클래스와 수량자는 정규식이 진정으로 강력해지는 부분입니다. 문자 범위를 일치시키고 패턴이 반복되어야 하는 횟수를 지정할 수 있습니다.
문자 클래스
문자 클래스는 정의된 집합에서 하나의 문자와 일치합니다. 대괄호로 묶입니다:
[abc]— a, b 또는 c와 일치[a-z]— 모든 소문자와 일치[A-Z0-9]— 모든 대문자 또는 숫자와 일치[^abc]— a, b, c를 제외한 모든 문자와 일치 (부정 클래스).— 개행 문자를 제외한 모든 문자와 일치
여러 범위를 결합할 수 있습니다: [a-zA-Z0-9]는 모든 영숫자 문자와 일치합니다.
단축 문자 클래스
이러한 사전 정의된 클래스는 시간을 절약하고 가독성을 향상시킵니다:
| 단축 | 동등 | 설명 |
|---|---|---|
\d |
[0-9] |
모든 숫자 |
\D |
[^0-9] |
모든 비숫자 |
\w |
[a-zA-Z0-9_] |
모든 단어 문자 (문자, 숫자, 밑줄) |
\W |
[^a-zA-Z0-9_] |
모든 비단어 문자 |
\s |
[ \t\n\r\f\v] |
모든 공백 문자 |
\S |
[^ \t\n\r\f\v] |
모든 비공백 문자 |
수량자
수량자는 앞의 요소가 일치해야 하는 횟수를 지정합니다:
*— 0회 이상 (탐욕적)+— 1회 이상 (탐욕적)?— 0회 또는 1회 (선택적){n}— 정확히 n회{n,}— 최소 n회{n,m}— n회에서 m회 사이 (포함)
예제: \d{3}-\d{2}-\d{4}는 "123-45-6789"와 같은 사회보장번호 형식과 일치합니다.
예제: colou?r는 "color"와 "colour" 모두와 일치합니다 ('u'는 선택적).
탐욕적 vs. 게으른 수량자
기본적으로 수량자는 탐욕적입니다—가능한 한 많은 텍스트와 일치합니다. 수량자 뒤에 ?를 추가하면 게으른 (비탐욕적)이 되어 가능한 한 적게 일치합니다:
*?— 0회 이상 (게으른)+?— 1회 이상 (게으른)??— 0회 또는 1회 (게으른){n,m}?— n회에서 m회 사이 (게으른)
예제: <div>content</div> 텍스트가 주어졌을 때, <.+> 패턴 (탐욕적)은 전체 문자열과 일치하는 반면, <.+?> (게으른)는 <div>만 일치합니다.
빠른 팁: 구분 기호 사이의 내용을 추출할 때 (HTML 태그나 따옴표 같은) 항상 게으른 수량자를 사용하여 너무 많이 일치하는 것을 방지하세요. ".*?" 패턴은 따옴표로 묶인 문자열을 올바르게 추출하는 반면, ".*"는 전체 줄에서 첫 번째 따옴표부터 마지막 따옴표까지 일치합니다.
그룹, 캡처, 역참조
그룹을 사용하면 여러 문자를 단일 단위로 처리하고 나중에 사용하기 위해 일치된 텍스트를 캡처할 수 있습니다. 복잡한 패턴과 텍스트 추출에 필수적입니다.
캡처 그룹
괄호 ()는 캡처 그룹을 생성합니다. 일치된 텍스트가 저장되어 나중에 참조할 수 있습니다:
(\d{3})-(\d{3})-(\d{4})
이 패턴은 전화번호와 일치하고 세 개의 그룹을 캡처합니다: 지역 코드, 접두사, 회선 번호. 대부분의 언어에서 이러한 캡처를 $1, $2, $3 또는 유사한 구문으로 액세스할 수 있습니다.
비캡처 그룹
때로는 수량자나 교체를 위해 그룹화가 필요하지만 텍스트를 캡처할 필요는 없습니다. 비캡처 그룹에는 (?:...)를 사용합니다:
(?:https?|ftp)://[^\s]+
이것은 http, https 또는 ftp로 시작하는 URL과 일치하지만 프로토콜을 별도로 캡처하지 않습니다. 비캡처 그룹은 캡처된 텍스트가 필요하지 않을 때 더 효율적입니다.
명명된 캡처 그룹
명명된 그룹은 정규식을 더 읽기 쉽고 유지 관리하기 쉽게 만듭니다. 구문은 언어에 따라 다릅니다:
- Python, .NET, PCRE:
(?P<name>...)또는(?<name>...) - JavaScript (ES2018+):
(?<name>...)
예제:
(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
이것은 날짜와 일치하고 연도, 월, 일에 대한 명명된 캡처를 생성하여 코드를 더 자체 문서화합니다.
역참조
역참조를 사용하면 패턴에서 이전에 캡처된 것과 동일한 텍스트를 일치시킬 수 있습니다:
\1,\2등 — 번호로 캡처된 그룹 참조\k<name>— 명명된 그룹 참조 (구문은 다양함)
예제: \b(\w+)\s+\1\b는 "the the"나 "is is"와 같은 반복된 단어와 일치합니다.
예제: (['"])(.*?)\1는 작은따옴표와 큰따옴표로 묶인 문자열 모두와 일치하며, 닫는 따옴표가 여는 따옴표와 일치하도록 보장합니다.
교체
파이프 문자 |는 OR 연산자로 작동합니다. 종종 그룹과 함께 사용됩니다:
(cat|dog|bird)
이것은 "cat", "dog" 또는 "bird"와 일치합니다. 교체 순서에 주의하세요—정규식 엔진은 왼쪽에서 오른쪽으로 대안을 시도하고 첫 번째 일치에서 멈춥니다.
전방탐색과 후방탐색 단언
둘러보기 단언은 앞이나 뒤에 오는 것을 기반으로 위치를 일치시키지만 해당 텍스트를 일치에 포함하지 않는 너비가 0인 단언입니다. 복잡한 일치 시나리오에 매우 강력합니다.
전방탐색 단언
전방탐색은 현재 위치 뒤에 오는 것을 확인합니다:
(?=...)— 긍정 전방탐색 (뒤에 ...가 와야 함)(?!...)— 부정 전방탐색 (뒤에 ...가 오면 안 됨)
예제: \d+(?= dollars)는 " dollars" 뒤에 오는 숫자와 일치하지만 " dollars"를 일치에 포함하지 않습니다.
예제: ^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,}$는 최소 하나의 대문자, 하나의 소문자, 하나의 숫자를 포함하고 최소 8자 이상인 비밀번호를 검증합니다.
후방탐색 단언
후방탐색은 현재 위치 앞에 오는 것을 확인합니다:
(?<=...)— 긍정 후방탐색 (앞에 ...가 와야 함)(?<!...)— 부정 후방탐색 (앞에 ...가 오면 안 됨)
예제: (?<=\$)\d+는 달러 기호 앞에 오는 숫자와 일치하지만 달러 기호를 일치에 포함하지 않습니다.
예제: (?<!un)happy는 "happy"와 일치하지만 "unhappy"와는 일치하지 않습니다.
전문가 팁: 둘러보기 단언은 문자를 소비하지 않고 여러 조건을 확인해야 하는 검증 시나리오에 완벽합니다. 컨텍스트를 기반으로 무언가를 일치시켜야 하지만 특정 부분만 추출하려는 경우에도 필수적입니다.
실용적인 둘러보기 예제
@ 기호 없이 이메일에서 도메인 추출:
(?<=@)[a-zA-Z0-9.-]+
쉼표가 뒤따르지 않는 단어 일치:
\b\w+\b(?!,)
마이너스 기호가 앞에 오지 않는 숫자 찾기 (양수만):
(?<!-)\b\d+\b
일반적인 패턴과 실제 예제
일반적인 개발 작업을 위한 검증된 정규식 패턴을 살펴보겠습니다. 이러한 패턴은 프로덕션 준비가 되어 있으며 실제 애플리케이션에서 발생하는 엣지 케이스를 처리합니다.
이메일 검증
엄격함과 실제 사용의 균형을 맞춘 실용적인 이메일 패턴:
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
이 패턴은 일반적인 이메일 형식을 허용하면서 명백한 오류를 방지합니다. RFC 준수 검증을 위해서는 전용 라이브러리 사용을 고려하세요—전체 RFC 5322 정규식은 6,000자가 넘습니다.
URL 일치
선택적 www가 있는 HTTP/HTTPS URL 일치:
https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)
대부분의 URL을 포착하는 더 간단한 버전:
https?://[^\s]+
전화번호
유연한 형식의 미국 전화번호:
^(\+1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$
다음과 같은 형식과 일치합니다:
- 123-456-7890
- (123) 456-7890
- +1 123 456 7890
- 1234567890
날짜 형식
ISO 8601 날짜 형식 (YYYY-MM-DD):
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
미국 날짜 형식 (MM/DD/YYYY):
^(0[1-9]|1[0-2])/(0[1-9]|[12]\d|3[01])/\d{4}$
IP 주소
IPv4 주소 검증:
^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$
이것은 각 옥텟이 0에서 255 사이인지 확인합니다.
신용카드 번호
기본 신용카드 형식 (선택적 공백 또는 대시 포함):
^\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}$
실제 검증을 위해서는 Luhn 알고리즘을 사용해야 합니다—정규식은 형식만 확인합니다.
16진수 색상
선택적 # 접두사가 있는 16진수 색상 코드 일치:
^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$
이것은 6자리 (#FF5733)와 3자리 (#F57) 형식 모두와 일치합니다.
사용자 이름 검증
밑줄과 하이픈이 있는 영숫자 사용자 이름, 3-16자:
^[a-zA-Z0-9_-]{3,16}$
비밀번호 강도
최소 8자, 대문자 하나, 소문자 하나, 숫자 하나, 특수 문자 하나 필요:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&