정규식이란?
정규 표현식(regular expression), 줄여서 정규식(regex)은 검색 패턴을 정의하는 문자 시퀀스입니다. 텍스트 패턴을 서술하기 위한 작은 전용 언어라고 생각하면 됩니다. 특정 단어를 검색하는 대신 "대문자로 시작하고 ing로 끝나는 단어" 또는 "정확히 5자리 숫자"처럼 패턴을 검색할 수 있습니다.
정규식은 거의 모든 프로그래밍 언어, 텍스트 에디터, 커맨드라인 도구, 텍스트 검색 인터페이스에서 지원됩니다. 기본기를 배워두면 환경을 가리지 않는 강력한 도구를 손에 넣게 됩니다.
리터럴 문자와 메타문자
가장 단순한 정규식은 그냥 문자열 그대로입니다. 패턴 `hello`는 텍스트에서 "hello"를 찾습니다. 하지만 진짜 힘은 메타문자 — 정규식 문법에서 특별한 의미를 가진 문자 — 에서 나옵니다.
점 `.`은 줄바꿈을 제외한 모든 단일 문자와 매칭됩니다. `h.t`은 "hat", "hot", "hit", 심지어 "h3t"도 매칭합니다. 캐럿 `^`은 줄의 시작, 달러 `$`는 줄의 끝을 의미합니다. `^Hello`는 줄 맨 앞에 있는 "Hello"만 매칭합니다.
대괄호 `[]`는 문자 클래스를 정의합니다. `[aeiou]`는 모음 하나, `[0-9]`는 숫자 하나, `[A-Za-z]`는 영문자 하나와 매칭됩니다. 대괄호 안에 캐럿을 넣으면 부정 — `[^0-9]`는 숫자가 아닌 문자와 매칭됩니다.
수량자
수량자는 패턴 요소의 반복 횟수를 제어합니다. `*`는 "0회 이상", `+`는 "1회 이상", `?`는 "0회 또는 1회"(선택 요소)를 의미합니다.
중괄호로 정확한 횟수를 지정합니다. `a{3}`은 연속된 "a" 3개, `a{2,5}`는 2~5개, `a{3,}`은 3개 이상입니다.
문자 클래스와 조합하면 진짜 유용해집니다. `[0-9]{3}-[0-9]{4}`는 "555-1234" 같은 패턴과 매칭됩니다. `[A-Z][a-z]+`는 대문자로 시작하는 단어와 매칭됩니다.
주요 축약 클래스
`[0-9]`를 반복 입력하기 귀찮으니 축약 클래스가 있습니다. `\d`는 숫자, `\w`는 단어 문자(영문자·숫자·밑줄), `\s`는 공백 문자(스페이스·탭·줄바꿈)와 매칭됩니다.
대문자로 쓰면 부정입니다. `\D`는 숫자 아닌 것, `\W`는 단어 문자 아닌 것, `\S`는 공백 아닌 것입니다.
그룹과 대안
괄호 `()`는 그룹을 만듭니다. 수량자를 여러 문자에 한꺼번에 적용하거나, 매칭된 텍스트를 캡처해 나중에 참조할 수 있습니다.
`(ha)+`는 "ha", "haha", "hahaha"와 매칭 — 플러스가 그룹 전체에 적용됩니다. 괄호 없이 `ha+`를 쓰면 "ha", "haa", "haaa"와 매칭 — 플러스가 "a"에만 적용되죠.
파이프 `|`는 OR 연산입니다. `cat|dog`은 "cat" 또는 "dog"과 매칭됩니다.
바로 쓸 수 있는 실전 예제
**이메일 검증(기본):** `^[\w.+-]+@[\w-]+\.[a-zA-Z]{2,}$`
**전화번호 추출:** `\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}`
**URL 감지:** `https?://[\w\-]+(\.[\w\-]+)+[/\w\-._~:?#@!$&'()*+,;=]*`
**날짜 형식:** `\d{4}[-/]\d{2}[-/]\d{2}`
**HTML 태그 제거:** `<[^>]+>`
앵커와 경계
줄 경계인 `^`와 `$` 외에 단어 경계 `\b`가 매우 유용합니다. `\bcat\b`는 독립된 단어 "cat"만 매칭하고, "category"나 "concatenate"는 건드리지 않습니다.
찾아 바꾸기에서 전체 단어만 매칭해야 할 때 필수입니다. 단어 경계 없이 "he"를 바꾸면 "the", "she", "here" 속의 "he"까지 바뀌어 버립니다.
탐욕적 vs. 게으른 매칭
기본적으로 수량자는 탐욕적(greedy) — 가능한 한 많은 텍스트를 매칭합니다. "start middle end"에서 `start.*end`는 문자열 전체를 매칭합니다. `.*`가 최대한 많이 잡은 뒤 "end"가 매칭될 만큼만 돌려주기 때문입니다.
수량자 뒤에 `?`를 붙이면 게으른(lazy) 매칭 — 가능한 한 적게 매칭합니다. `start.*?end`는 첫 번째 "end"에서 멈춥니다.
HTML 태그 추출 시 이 차이가 중요합니다. 탐욕적 `<.*>`은 줄의 첫 `<`부터 마지막 `>`까지 통째로 잡지만, 게으른 `<.*?>`은 각 태그를 개별적으로 잡습니다.
더 나은 정규식을 쓰는 팁
단순하게 시작하고 점차 복잡하게. 목표를 매칭하는 패턴을 쓰고, 테스트한 뒤, 오탐을 줄여가세요. 한 번에 완벽한 정규식을 쓰려는 시도는 대부분 실패합니다.
온라인 정규식 테스터를 활용하세요. regex101.com 같은 도구에서 실시간 매칭, 패턴 설명, 캡처 그룹 하이라이팅을 확인할 수 있습니다.
복잡한 패턴에는 주석을 달아두세요. 대부분의 정규식 엔진이 공백과 주석을 허용하는 verbose 모드를 지원합니다.
정규식을 쓰지 말아야 할 때를 아는 것도 중요합니다. HTML, JSON, 프로그래밍 언어처럼 중첩 구조를 파싱하는 건 정규식이 아니라 전용 파서의 영역입니다. 정규식은 텍스트의 평면적 패턴에 가장 잘 맞습니다.