그 유명한 Stack Overflow 답변
Stack Overflow에 "정규식으로 HTML을 파싱하는 법"을 물으면 "He comes."로 끝나는 과격한 명답이 따라와. 표현은 과하지만 교훈은 정확해. 정규식은 파서가 아냐.
정규식이 진짜 못 하는 것
중첩 구조. 깊이가 정해지지 않은 괄호의 짝을 맞추는 일은 정규 언어가 아냐. ((a))와 (((a)))를 구분하려면 깊이를 세어야 하고, 순수 정규식은 그 수를 기억하지 못해. 일부 PCRE 엔진은 재귀 (?R)를 추가해 흉내 내지만 이미 고전적인 정규식의 범위를 벗어난 기능이야.
HTML / XML / Markdown / JSON / YAML / 소스 코드. 모두 중첩 구조를 품고 있어. Python의 html.parser·lxml·json·yaml, JavaScript의 DOMParser·JSON.parse처럼 형식에 맞는 파서를 써.
의미 검증. 정규식은 모양은 확인하지만 의미는 판단하지 못해. \d{4}는 "9999"도 매칭해. 그 값이 유효한 연도인지는 일반 코드가 판단해야 해.
Unicode의 깊은 문제. 오른쪽에서 왼쪽으로 쓰는 문자 체계, 이모지 ZWJ 시퀀스, 결합 문자, 로캘별 대소문자 변환은 전용 라이브러리의 영역이야. 정규식이 \p{...}와 Unicode 플래그로 일부를 *건드릴* 수는 있지만 대개 알맞은 도구가 아니야.
위험 신호
패턴이 100자를 넘고, 그룹이 네 겹 이상 중첩되고, 후방 탐색으로 주변 맥락을 기억하려 한다면 멈춰. 매칭이 아니라 파싱을 시도하는 중일 가능성이 커. HTML 파서, YAML 라이브러리, 토크나이저, AST 순회 도구처럼 구조를 다루는 도구를 꺼내.
정규식은 모양을 감지해. 문제가 구조로 바뀌는 순간 다음 도구에 넘겨야 해.