모든 아티클

정규 표현식: 기초와 탐욕적 매칭의 함정

정규 표현식(regex)은 텍스트 패턴을 간결하게 기술하는 방법입니다. 특정 문자열이 아니라 문자열이 만족해야 할 규칙을 나타냅니다. 반복문으로 문자를 하나씩 검사하는 대신, 하나의 표현식으로 복잡한 구조를 찾거나 검증할 수 있습니다.

기본 구성 요소

  • 문자 클래스\d(숫자), \w(문자/숫자/밑줄), \s(공백), 또는 [a-zA-Z]처럼 직접 정의한 클래스.
  • 수량자*(0회 이상), +(1회 이상), ?(0회 또는 1회), {2,5}(2~5회).
  • 캡처 그룹 — 괄호 (...)는 매치의 일부를 표시해 나중에 치환 등에서 따로 활용할 수 있게 한다.
  • 앵커^$는 패턴을 줄의 시작이나 끝에 고정한다.

\w가 한글을 인식하지 못하는 이유

이 도구가 사용하는 JavaScript 정규식 엔진에서 \w는 항상 [A-Za-z0-9_]만을 의미합니다 — ASCII 영문자, 숫자, 밑줄뿐입니다. 그래서 /^\w+$/.test('안녕하세요')false를 반환하며, 한글 자모든 완성형 음절이든 전혀 매치되지 않습니다. u 플래그를 추가해도 \w 자체의 정의가 넓어지지는 않으므로, 한글을 제대로 잡으려면 /^\p{L}+$/u처럼 유니코드 속성 기반의 "임의의 문자" 클래스를 명시적으로 써야 합니다. 입력 폼에서 아이디나 필수 항목을 \w+로 검증하면 한글 이름이나 한글 값이 이유 없이 거부되는 버그가 흔히 발생합니다.

탐욕적 매칭과 게으른 매칭

수량자는 기본적으로 "탐욕적"이라서 가능한 한 많은 문자를 매치하려 하고, 그것이 매치를 방해할 때만 물러섭니다. 예를 들어 <.+><a>text</a>에서 첫 <부터 마지막 >까지 전부를 잡아버립니다. 수량자 뒤에 ?를 붙이면(<.+?>) "게으른" 매칭이 되어 가능한 한 적게 매치하고 첫 번째 유효한 매치에서 멈춥니다.

어디에 쓰이는가

  • 입력 데이터의 형식 검증(이메일, 전화번호, 우편번호).
  • 정확한 일치가 아닌 패턴 기반의 텍스트 검색과 일괄 치환.
  • 로그나 비정형 텍스트에서 구조화된 데이터 추출.

파국적 백트래킹

(a+)+처럼 중첩된 수량자는 특정 입력에서 정규식 엔진이 매치가 없다고 결론 내리기 전에 지수적으로 많은 조합을 시도하게 만들 수 있습니다 — 겉보기엔 단순한 표현식 때문에 페이지나 서버가 "멈춰버립니다". 이는 실제 존재하는 취약점 유형(ReDoS)이므로, 복잡한 중첩 수량자는 예상된 예시뿐 아니라 길고 "거의 매치되는" 문자열로도 반드시 테스트해야 합니다.

도구 사용해보기