정규표현식 입문: 텍스트 처리의 강력한 도구

정규표현식 입문: 텍스트 처리의 강력한 도구

정규표현식이란 무엇인가?

정규표현식(Regular Expression, 줄여서 Regex)은 텍스트에서 특정 패턴을 찾고, 추출하고, 치환하는 강력한 도구입니다. 프로그래밍 언어가 아닌 ‘패턴 매칭 언어’로, Python, JavaScript, Java, PHP 등 거의 모든 프로그래밍 언어에서 지원합니다.

정규표현식은 1950년대 수학자 스티븐 클레인(Stephen Kleene)이 정규 집합(regular set)을 설명하기 위해 고안한 표기법에서 유래했습니다. 1968년 켄 톰슨(Ken Thompson)이 Unix의 텍스트 에디터 ed에 정규표현식을 구현하면서 프로그래밍 도구로 자리잡았습니다.

왜 정규표현식을 배워야 하나요?

  • 이메일 검증: 사용자 입력이 유효한 이메일 형식인지 확인
  • 로그 파싱: 서버 로그에서 IP 주소나 에러 메시지 추출
  • 데이터 추출: HTML에서 전화번호나 URL 찾기
  • 코드 리팩토링: 수백 개 파일에서 함수명 일괄 변경
  • 텍스트 변환: 날짜 형식 변환, 공백 정리 등

기본 문법: 메타문자와 리터럴

리터럴 문자

정규표현식의 가장 기본은 일반 문자 그대로 매칭하는 것입니다. cat이라는 정규식은 텍스트에서 “cat”이라는 문자열을 찾습니다.

메타문자 (특수 의미)

메타문자 의미 예시 매칭 결과
. 임의의 한 문자 c.t cat, cot, c9t, c@t
^ 문자열 시작 ^Hello Hello로 시작하는 줄
$ 문자열 끝 world$ world로 끝나는 줄
* 0회 이상 반복 ab*c ac, abc, abbc, abbbc
+ 1회 이상 반복 ab+c abc, abbc (ac는 안됨)
? 0 또는 1회 colou?r color, colour
{n} 정확히 n회 \d{3} 123, 999
{n,} n회 이상 \d{2,} 12, 123, 12345
{n,m} n~m회 \d{2,4} 12, 123, 1234
[] 문자 클래스 [aeiou] 모음 한 글자
| OR 연산 cat|dog cat 또는 dog
\ 이스케이프 \. 마침표 문자 그대로

문자 클래스

클래스 의미 동등 표현
\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]

자주 쓰는 패턴 라이브러리

1. 이메일 주소

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

설명:

  • ^: 문자열 시작
  • [a-zA-Z0-9._%+-]+: 로컬 파트 (1자 이상)
  • @: @ 기호
  • [a-zA-Z0-9.-]+: 도메인명
  • \.: 점 (이스케이프 필요)
  • [a-zA-Z]{2,}: 최상위 도메인 (2자 이상)
  • $: 문자열 끝

2. 전화번호 (한국)

^01[0-9]-\d{3,4}-\d{4}$

매칭 예시: 010-1234-5678, 011-123-4567

3. URL

https?://[^\s]+

설명:

  • https?: http 또는 https
  • ://: 프로토콜 구분자
  • [^\s]+: 공백이 아닌 문자 1개 이상

4. IP 주소 (IPv4)

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

매칭 예시: 192.168.0.1, 255.255.255.255

5. 한글

[가-힣]+

설명: 완성형 한글 자모 범위 (가~힣)

6. 날짜 (YYYY-MM-DD)

^\d{4}-\d{2}-\d{2}$

매칭 예시: 2026-02-02, 1999-12-31

그룹과 캡처: 패턴 재사용

캡처 그룹 ( )

괄호로 묶인 부분은 “그룹”이 되며, 매칭된 내용을 추출하거나 재사용할 수 있습니다.

(\d{4})-(\d{2})-(\d{2})

예시: “2026-02-02″를 매칭하면

  • 그룹 1: 2026 (연도)
  • 그룹 2: 02 (월)
  • 그룹 3: 02 (일)

비캡처 그룹 (?:)

그룹으로 묶되 캡처하지 않을 때 사용합니다 (성능 향상).

(?:https?|ftp)://[^\s]+

역참조 (Backreference)

앞에서 캡처한 그룹을 다시 참조할 수 있습니다.

<(\w+)>.*?</\1>

설명: HTML 태그 매칭 (여는 태그와 닫는 태그 동일)

  • (\w+): 태그명 캡처
  • \1: 첫 번째 그룹 참조

매칭 예시: <div>...</div>, <p>...</p>

실전 예제

예제 1: 이메일 유효성 검사 (JavaScript)

function validateEmail(email) {
    const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
    return regex.test(email);
}

console.log(validateEmail("user@example.com")); // true
console.log(validateEmail("invalid-email"));    // false

예제 2: 로그에서 IP 주소 추출 (Python)

import re

log = "2026-02-02 10:30:15 192.168.1.100 GET /api/users 200"
ip_pattern = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
ip = re.search(ip_pattern, log)

print(ip.group())  # 192.168.1.100

예제 3: 텍스트 치환 (날짜 형식 변환)

import re

text = "오늘은 2026-02-02입니다."
# YYYY-MM-DD → DD/MM/YYYY
new_text = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\3/\2/\1', text)

print(new_text)  # 오늘은 02/02/2026입니다.

예제 4: HTML 태그 제거

import re

html = "<p>Hello <strong>World</strong></p>"
clean = re.sub(r'<[^>]+>', '', html)

print(clean)  # Hello World

성능과 보안 주의사항

ReDoS 공격 (Regular Expression Denial of Service)

복잡한 정규식은 백트래킹 폭발로 인해 CPU를 과도하게 사용할 수 있습니다.

위험한 패턴 예시:

(a+)+b

문제: “aaaaaaaaaaaaaaaaaaa”를 처리할 때 지수 시간 복잡도

ReDoS 방지법

  • 중첩 수량자 피하기: (a+)+, (a*)* 같은 패턴 제거
  • 타임아웃 설정: Python re 대신 regex 라이브러리 사용 (timeout 옵션)
  • 입력 길이 제한: 사용자 입력을 검증하기 전에 길이 체크
  • 비캡처 그룹 사용: (?:...)로 불필요한 캡처 제거

성능 최적화 팁

느린 패턴 빠른 패턴 이유
.* [^\s]+ 구체적인 클래스가 백트래킹 감소
(a|b|c) [abc] 문자 클래스가 더 빠름
^.*keyword.*$ keyword 앵커와 .* 불필요

학습 도구와 리소스

추천 학습 사이트

ToolZipper 정규식 도구

결론

정규표현식은 처음엔 복잡해 보이지만, 기본 패턴만 익히면 텍스트 처리 생산성이 크게 향상됩니다. 이메일 검증, 로그 파싱, 데이터 추출 등 실무에서 매일 사용하는 필수 기술입니다.

핵심 요약

  • 정규표현식은 ‘패턴 매칭 언어’로 거의 모든 프로그래밍 언어에서 지원
  • 메타문자 . ^ $ * + ? {} [] | \와 문자 클래스 \d \w \s 이해 필수
  • 이메일: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
  • 캡처 그룹 ( )으로 데이터 추출, 역참조 \1로 재사용
  • ReDoS 공격 주의: 중첩 수량자 (a+)+ 피하기

지금 바로 정규식 테스터에서 연습해보세요!

문의하기