목록으로
유틸리티

정확한 정규식 작성하는 방법 5가지 실전 원칙

정확한 정규식은 "일단 매칭되는 패턴"이 아니라 "매칭되어야 할 것만 매칭되는 패턴"을 뜻합니다. 대부분의 정규식 버그는 문법 오류가 아니라 의도보다 넓게 잡히거나 좁게 잡히는 범위 설계에서 발생합니다. 아래 다섯 가지 원칙을 지키면 실무에서 겪는 오탐 대부분을 없앨 수 있습니다.

1. 앵커로 검사 범위를 고정합니다

가장 흔한 실수는 앵커를 빠뜨리는 것입니다. \d{3}-\d{4} 라는 패턴은 abc123-4567xyz 안에서도 매칭됩니다. 문자열 전체가 형식에 맞는지 확인하려면 반드시 시작과 끝을 고정해야 합니다.

  • ^ : 문자열(또는 줄)의 시작
  • $ : 문자열(또는 줄)의 끝
  • \b : 단어 경계, 문장 속에서 특정 단어만 뽑을 때 사용
주의: 자바스크립트와 파이썬에서 $는 문자열 끝의 개행 문자 하나를 허용합니다. ^\d+$"123\n"에도 매칭되므로, 엄격한 검증이 필요하면 파이썬은 \Z, 자바스크립트는 사전에 trim 처리를 하는 편이 안전합니다.

2. 탐욕적 수량자를 통제합니다

정규식의 *, +, {n,}는 기본적으로 탐욕적(greedy)이라 가능한 한 길게 먹습니다. HTML 태그를 뽑으려고 <.*>를 쓰면 첫 태그부터 마지막 태그까지 통째로 잡히는 이유가 이것입니다.

방식패턴동작
탐욕적<.*>가능한 최대 길이로 매칭
게으른<.*?>가능한 최소 길이로 매칭
부정 문자 클래스<[^>]*>최소 매칭 + 성능 우수

세 번째 방식을 권장합니다. 게으른 수량자는 백트래킹을 반복하지만, 부정 문자 클래스는 한 번의 스캔으로 끝나기 때문에 긴 문자열에서 속도 차이가 크게 벌어집니다.

3. 점(.) 대신 구체적인 문자 클래스를 씁니다

점 하나는 개행을 제외한 모든 문자를 의미합니다. 편하지만 정확도를 가장 크게 떨어뜨리는 요소이기도 합니다. 날짜를 잡을 때 \d{4}.\d{2}.\d{2}라고 쓰면 2026x07y21 같은 값도 통과합니다. 구분자가 하이픈이나 점이라면 [-.]처럼 명시하는 편이 낫습니다.

팁: 한글을 다룰 때는 [가-힣]이 완성형 음절만 포함한다는 점을 기억하세요. 자음과 모음 단독 입력(ㄱ, ㅏ)까지 허용하려면 [가-힣ㄱ-ㅎㅏ-ㅣ]로 확장해야 합니다.

4. 실제 데이터로 양성과 음성 케이스를 모두 검증합니다

정확한 정규식인지 판단하려면 "통과해야 할 값"뿐 아니라 "절대 통과하면 안 되는 값"을 함께 넣어봐야 합니다. 이메일 검증을 예로 들면 다음과 같은 케이스를 준비합니다.

  1. 통과: [email protected], [email protected]
  2. 차단: user@@example.com, @example.com, user@example, user @example.com

패턴을 수정할 때마다 이 목록 전체를 다시 돌려야 회귀를 잡을 수 있습니다. 매칭 결과와 캡처 그룹을 즉시 확인하려면 정규식 테스터에 케이스를 붙여넣고 패턴을 조금씩 바꿔가며 비교하는 방식이 가장 빠릅니다.

정규식은 작성하는 시간보다 검증하는 시간이 길어야 정확해집니다.

5. 파국적 백트래킹을 피합니다

중첩된 수량자는 성능 재앙의 원인입니다. (a+)+$처럼 반복 안에 반복이 들어가면, 매칭에 실패하는 입력에서 경우의 수가 지수적으로 늘어나 서버가 멈추기도 합니다. 이를 ReDoS라고 부릅니다.

  • 중첩 수량자 (x+)+, (x*)* 형태를 발견하면 즉시 단순화합니다
  • 선택지끼리 겹치는 (a|ab)+ 같은 패턴도 백트래킹을 유발합니다
  • 사용자 입력을 정규식 패턴 자체로 받는 구조는 만들지 않습니다
참고: 자바와 닷넷은 원자 그룹 (?>...)과 소유 수량자 *+를 지원해 백트래킹을 원천 차단할 수 있습니다. 자바스크립트에는 없으므로, 대신 입력 길이를 제한하거나 정규식 대신 문자열 분할 로직으로 대체하는 방법을 고려합니다.

정리

정확도를 높이는 순서는 명확합니다. 먼저 앵커로 범위를 닫고, 수량자를 최소 매칭으로 바꾸고, 점을 구체적인 문자 클래스로 교체한 뒤, 음성 케이스로 검증하고, 마지막으로 중첩 수량자를 점검합니다. 이 다섯 단계를 거친 패턴은 대부분의 실무 요구를 안정적으로 처리합니다. 반대로 형식이 지나치게 복잡한 대상, 예를 들어 중첩 구조를 가진 HTML이나 JSON은 정규식이 아니라 전용 파서를 쓰는 것이 정답입니다.

자동차 수리가 필요하신가요?

대전 사고차 수리 전문 - 남대전자동차공업사

무료 견적받기