정규식 패턴은 문자열 속에서 원하는 형태를 찾아내기 위한 규칙 표현식입니다. 이메일 형식 검증, 로그 파일 분석, 대량 텍스트 치환처럼 사람이 하나하나 처리하기 어려운 작업을 한 줄로 끝낼 수 있게 해줍니다.
처음 보면 암호처럼 느껴지지만, 실제 현업에서 반복적으로 쓰이는 형태는 열 개 남짓입니다. 기본 문법과 자주 쓰는 예제, 그리고 많은 개발자가 빠지는 함정까지 순서대로 살펴보겠습니다.
정규식 패턴의 기본 구조
정규식은 크게 세 가지 요소로 이루어집니다. 무엇을 찾을지 정하는 문자 클래스, 몇 번 반복될지 정하는 수량자, 그리고 위치를 고정하는 앵커입니다. 이 세 가지만 이해해도 대부분의 패턴을 읽을 수 있습니다.
| 기호 | 의미 | 예시 |
|---|---|---|
| . | 개행을 제외한 모든 문자 1개 | a.c 는 abc, a1c 매칭 |
| \d | 숫자 한 자리 (0-9) | \d\d 는 42 매칭 |
| \w | 영문자, 숫자, 밑줄 | \w+ 는 user_01 매칭 |
| \s | 공백, 탭, 개행 | a\sb 는 a b 매칭 |
| * | 0회 이상 반복 | ab* 는 a, ab, abb 매칭 |
| + | 1회 이상 반복 | ab+ 는 ab, abb 매칭 |
| ? | 0회 또는 1회 | colou?r 는 color, colour 매칭 |
| {n,m} | n회 이상 m회 이하 | \d{2,4} 는 12, 1234 매칭 |
| ^ $ | 문자열의 시작과 끝 | ^abc$ 는 abc만 매칭 |
| [ ] | 대괄호 안의 문자 중 하나 | [aeiou] 는 모음 1개 |
실무에서 자주 쓰는 정규식 패턴 10가지
아래 패턴들은 검증 로직이나 데이터 정제 작업에서 반복적으로 등장합니다. 그대로 복사해 쓰기보다는 어떤 구조로 짜였는지 한 번씩 뜯어보면 응용 범위가 훨씬 넓어집니다.
- 이메일 주소 :
^[\w.-]+@[\w-]+\.[a-zA-Z]{2,}$아이디, 골뱅이, 도메인, 최상위 도메인 순으로 구성됩니다. - 휴대폰 번호 :
^01[016789]-?\d{3,4}-?\d{4}$하이픈 유무를 모두 허용합니다. - URL :
https?:\/\/[\w.-]+(\/[\w./?%&=-]*)?http와 https를 함께 처리합니다. - 숫자만 추출 :
\d+문자열 중 연속된 숫자 덩어리를 전부 찾아냅니다. - 한글만 추출 :
[가-힣]+완성형 한글 음절 범위를 지정합니다. - 날짜 형식 :
^\d{4}-\d{2}-\d{2}$YYYY-MM-DD 형태를 검사합니다. - 비밀번호 규칙 :
^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%]).{8,}$전방 탐색으로 조건을 중첩합니다. - 중복 공백 정리 :
\s{2,}를 공백 하나로 치환하면 문서 정리가 끝납니다. - IP 주소 :
^(\d{1,3}\.){3}\d{1,3}$형식만 빠르게 거를 때 유용합니다. - HTML 태그 제거 :
<[^>]+>를 빈 문자열로 치환해 텍스트만 남깁니다.
패턴을 수정할 때마다 코드를 실행해 결과를 확인하면 시간이 많이 듭니다. 이럴 때는 정규식 테스터에 샘플 문자열을 넣고 매칭되는 부분을 실시간으로 확인하면 훨씬 빠르게 다듬을 수 있습니다.
정규식 패턴 작성 시 흔한 실수
정규식은 문법 오류가 없어도 의도와 다르게 동작하는 경우가 많습니다. 특히 다음 세 가지는 실무에서 자주 발생하는 문제입니다.
첫째, 탐욕적 수량자를 그대로 쓰는 경우입니다. <.*> 로 태그를 찾으면 첫 번째 여는 괄호부터 마지막 닫는 괄호까지 전부 하나로 잡아버립니다. 최소 매칭을 원한다면 <.*?> 처럼 물음표를 붙이거나, 아예 <[^>]*> 처럼 부정 문자 클래스를 쓰는 편이 정확합니다.
둘째, 마침표를 이스케이프하지 않는 경우입니다. 파일 확장자를 검사하려고 .jpg 라고 쓰면 마침표가 임의의 문자로 해석되어 ajpg, 1jpg 같은 문자열도 통과합니다. 정확히는 \.jpg$ 로 써야 합니다.
셋째, 앵커를 빠뜨리는 경우입니다. 유효성 검사에서 ^ 와 $ 를 생략하면 문자열 일부만 일치해도 참이 됩니다. [email protected]!!!! 같은 값이 통과하는 사고가 대부분 여기서 나옵니다.
언어별 정규식 패턴의 차이
정규식은 표준이 하나가 아닙니다. 대부분 PCRE 계열을 따르지만 세부 문법에서 차이가 있어, 다른 언어에서 가져온 패턴이 그대로 동작하지 않을 수 있습니다.
| 언어 | 특징 | 주의점 |
|---|---|---|
| JavaScript | 슬래시로 감싸는 리터럴 문법 | 후방 탐색은 구형 브라우저 미지원 |
| Python | re 모듈, 원시 문자열 권장 | r 접두사 없으면 백슬래시 중복 필요 |
| Java | 문자열 안에 작성 | \d 를 \\d 로 두 번 써야 함 |
| PHP | 구분자 필요 | preg_match 에서 패턴을 슬래시로 감쌈 |
| MySQL | REGEXP 연산자 | \d 대신 [0-9] 사용 권장 |
성능을 고려한 정규식 패턴 작성법
정규식은 편리하지만 비용이 있는 연산입니다. 대량의 데이터를 처리한다면 다음 원칙을 지키는 것만으로도 속도가 눈에 띄게 달라집니다.
- 반복문 안에서 매번 정규식을 생성하지 말고, 컴파일된 객체를 바깥에서 한 번만 만들어 재사용합니다.
- 단순 포함 여부 확인이라면 정규식 대신 문자열 함수를 쓰는 편이 훨씬 빠릅니다.
- 가능하면 앵커를 붙여 탐색 범위를 좁힙니다. 시작 위치가 고정되면 엔진이 불필요한 시도를 건너뜁니다.
- 캡처가 필요 없는 그룹은 (?:...) 형태의 비캡처 그룹으로 바꿔 메모리 사용을 줄입니다.
- 중첩 수량자는 피하고, 문자 클래스로 대체할 수 있는지 먼저 검토합니다.
정규식은 결국 도구입니다. 모든 문자열 처리를 하나의 패턴으로 해결하려 하기보다, 복잡해진다 싶으면 여러 단계로 나누거나 전용 파서를 쓰는 판단이 더 나은 결과를 만듭니다. 특히 HTML이나 JSON처럼 구조를 가진 데이터는 정규식보다 전용 라이브러리를 쓰는 것이 정확하고 안전합니다.