"invalid regular expression" 및 일반적인 정규식 오류 해결: 완벽 가이드
정규 표현식(Regex)은 패턴 매칭과 텍스트 조작에 매우 강력합니다. 하지만 밀집된 구문과 난해한 오류 메시지로도 유명합니다. 작은 오타 하나가 invalid regular expression 오류를 일으켜 코드를 중단시킬 수 있습니다.
이 가이드에서는 가장 일반적인 정규식 오류를 분석하고, 발생 원인을 설명하며, 효율적으로 수정하는 방법을 보여줍니다.
1. 일반적인 정규식 오류 메시지
환경에 따라 다음과 같은 오류가 발생할 수 있습니다.
- JavaScript (RegExp):
SyntaxError: Invalid regular expression: ... - Python (re):
re.error: ... - Java:
java.util.regex.PatternSyntaxException: ... - C#:
System.ArgumentException: ...
2. 주요 구문 오류와 해결책
2.1 "unterminated character class" (종료되지 않은 문자 클래스)
[로 문자 클래스를 시작했지만 ]로 닫는 것을 잊었을 때 발생합니다.
오류 예시:
const regex = /[a-z/ // SyntaxError: Invalid regular expression: /[a-z/: unterminated character class
해결책:
모든 [에 대응하는 ]가 있는지 확인하세요.
const regex = /[a-z]/ // 정답
2.2 "invalid group" 또는 "unterminated group" (종료되지 않은 그룹)
문자 클래스와 마찬가지로 괄호 ()의 쌍이 맞지 않을 때 발생합니다.
오류 예시:
const regex = /(abc/ // SyntaxError: Invalid regular expression: /(abc/: unterminated group
해결책: 괄호의 쌍을 맞추세요.
const regex = /(abc)/ // 정답
2.3 "regex lookahead not supported" (전방 탐색 미지원)
일부 오래된 정규식 엔진이나 특정 구현에서는 '전방 탐색(lookahead)'((?=...)) 또는 '후방 탐색(lookbehind)'((?<=...))과 같은 고급 기능을 지원하지 않을 수 있습니다.
오류 현상:
regex lookahead not supported (일부 레거시 시스템이나 단순 파서에서 흔함)
해결책: 사용 중인 환경이 이러한 기능을 지원하는지 확인하세요. JavaScript에서 후방 탐색은 ES2018에서 추가되었습니다. 호환성이 필요한 경우 이러한 구조를 피하도록 정규식을 리팩터링해야 합니다.
3. 성능 및 런타임 오류
3.1 "regex catastrophic backtracking" (파괴적인 역추적)
가장 위험한 정규식 오류 중 하나입니다. 중첩된 수량자(예: (a+)+)가 포함된 복잡한 정규식이 거의 일치하지만 결국 실패하는 문자열을 만났을 때 발생합니다. 엔진은 수만 가지 조합을 시도하며 CPU 점유율을 100%까지 끌어올리고 애플리케이션을 멈추게 합니다.
증상: 코드가 멈추거나 작은 문자열을 처리하는 데 몇 초가 걸립니다.
해결책:
- 중첩된 수량자 피하기:
*,+,{n,}을 서로 중첩하지 마세요. - 구체적으로 작성하기:
.*대신[^"\n]*와 같이 더 구체적인 문자 클래스를 사용하세요. - 소유적 수량자/원자적 그룹 사용: (엔진이 지원하는 경우) 엔진이 실패한 경로를 다시 시도하지 않도록 합니다.
3.2 "regex timeout" (정규식 시간 초과)
Cloudflare, 데이터베이스 엔진 또는 온라인 IDE와 같은 많은 현대적인 플랫폼은 파괴적인 역추적을 방지하기 위해 정규식 실행에 엄격한 시간 초과를 적용합니다.
오류 예시:
regex timeout
해결책:
성능을 위해 정규식을 최적화하세요. 복잡한 패턴을 더 작고 단순한 체크로 나누거나, 정규식을 적용하기 전에 indexOf나 startsWith 같은 문자열 메서드를 사용하여 기본 일치를 확인하세요.
4. 예방 조치 및 모범 사례
v플래그 사용 (JavaScript): 최신 JS에서v플래그는 더 나은 유니코드 지원과 강력한 오류 검사를 제공합니다.- 단계별 테스트: 거대한 정규식을 한 번에 작성하지 마세요. 조금씩 빌드하고 각 부분을 테스트하세요.
- 이스케이프:
.,*,+,?,^,$,(,),[,],{,},|,\와 같은 특수 문자를 문자 그대로 매칭하려면 항상 이스케이프를 잊지 마세요. - Try-Catch 사용: 사용자 입력으로 정규식을 생성하는 경우 항상 try-catch 블록을 사용하세요.
function createSafeRegex(pattern) {
try {
return new RegExp(pattern);
} catch (e) {
console.error("잘못된 사용자 정규식:", e.message);
return null;
}
}
5. 자주 묻는 질문 (FAQ)
Q: JavaScript에서 슬래시 /를 왜 이스케이프해야 하나요?
A: JavaScript는 /를 정규식 리터럴의 구분자로 사용하기 때문입니다 (예: /pattern/). 패턴에 /가 포함된 경우 \/로 작성해야 합니다. 또는 / 이스케이프가 필요 없는 new RegExp("pattern") 생성자를 사용하세요.
Q: .*와 .*?의 차이점은 무엇인가요?
A: .*는 탐욕적(greedy)(가능한 한 많이 매칭)이고, .*?는 게으른(lazy)(가능한 한 적게 매칭)입니다. 게으른 수량자를 사용하면 역추적 문제를 방지하는 데 도움이 되는 경우가 많습니다.
Q: 정규식으로 HTML을 파싱할 수 있나요?
A: 일반적으로 권장하지 않습니다. HTML은 '정규' 언어가 아니라 문맥 자유 언어입니다. 정규식으로 복잡한 HTML을 파싱하는 것은 오류가 발생하기 매우 쉬우며 파괴적인 역추적으로 이어질 수 있습니다. 적절한 DOM 파서를 사용하세요.
6. 빠른 확인 도구
작동하지 않는 정규식으로 고생하고 계신가요? 당사의 **온라인 정규식 테스터 및 디버거**를 사용해 보세요. 다음 기능을 제공합니다.
- 입력 시 실시간 매칭.
- 정규식의 각 부분에 대한 상세한 설명.
- 성능 문제를 경고하는 역추적(backtracking) 감지.
- 여러 프로그래밍 언어에 대한 코드 생성.
관련 오류
- JSON의 'Unexpected token' 오류 해결 방법
- JavaScript에서 'URIError: URI malformed' 수정 방법
- 'invalid base64 string' 오류 해결 방법