RegExp.escape()에서의 이스케이핑: 문자, 숫자, 공백이 왜 \x 코드로 변하는가
2025년에 브라우저에 도입된 RegExp.escape() 함수는 regex 메타문자뿐만 아니라 라틴 문자, 선행 숫자, 공백, 그리고 @ 같은 구두점도 이스케이프합니다. 이는 이러한 문자를 무시하는 전통적인 직접 구현 이스케이프 함수들과 차별화되는 점입니다. ECMAScript 표준은 RegExp 연결 시 오류를 방지하기 위해 이를 요구합니다.
숫자와 문자를 이스케이프하는 이유
선행 숫자는 캡처 그룹 번호나 8진 코드로 해석되는 것을 피하기 위해 이스케이프됩니다. 라틴 문자는 \c 같은 이스케이프 시퀀스를 제대로 처리하기 위함입니다.
숫자 예시:
p = '2'
new RegExp('()\\1' + RegExp.escape(p)).source // ()\\1\\x32
new RegExp('()\\1' + p).source // ()\\12
이스케이프하지 않으면 \12는 12번째 그룹이나 8진 코드 12에 해당하는 문자를 가리킵니다. 이스케이프하면 그룹 1 뒤에 문자 2가 오는 것으로 매칭됩니다.
문자 예시:
p = 'a'
new RegExp('\\c' + RegExp.escape(p)).source // \\c\\x61
new RegExp('\\c' + p).source // \\ca
\ca는 제어 문자(코드 1)로 해석되지만, \c\x61은 \c 뒤에 a가 오는 시퀀스입니다. Unicode 모드(u 또는 v)에서는 이런 구문이 SyntaxError를 발생시켜 디버깅을 쉽게 합니다.
공백과 구두점: 사전적 보호
표준은 공백과 @ 같은 문자를 이스케이프하는 이유를 설명하지 않습니다. TC39 저장소에 따르면 미래에 "컨텍스트 이스케이프"를 유발할 수 있는 모든 문자를 이스케이프한다고 합니다. 이는 컨텍스트 진입과 종료를 공백이나 ASCII 구두점으로만 제한합니다.
이 접근 방식은 논쟁적입니다. 현재 필요 없이 오버헤드를 추가하기 때문입니다. 공백을 무시하는 x 플래그 제안은 4단계 중 1단계에 머물러 있습니다.
직접 구현 함수와 비교
MDN(2020)의 고전 이스케이프 함수:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\\]\\]/g, '\\$&');
}
메타문자는 커버하지만 숫자나 문자는 아닙니다. 선행 숫자와 하이픈을 이스케이프하는 개선 버전:
function escapeRegExp(string) {
const coolCmd = string => string.replace(/[.*+?^${}()|[\\]\\]/g, '\\$&')
.replaceAll('-', '\\x2d');
const charCode = string.charCodeAt(0);
return charCode >= 0x30 && charCode <= 0x39
? `\\x${charCode.toString(16)}${coolCmd(string.slice(1))}`
: coolCmd(string);
}
| 항목 | RegExp.escape() | 사용자 정의 (개선됨) |
|--------------------|------------------|-------------------|
| 선행 숫자 | \x32 | \x32 |
| 라틴 문자 | \x61 | 없음 |
| 공백/@ | \x20/\x40 | 없음 |
| 성능 | 네이티브 | RegExp 기반 |
사용 권장사항
- 새 코드: 구 버전 환경을 위해 폴리필과 함께
RegExp.escape()사용. - Unicode 모드: 항상
u플래그 추가—파싱 시점에 오류를 잡음. - ESLint:
@eslint/regexp/no-octal-escape규칙과require-unicode-regexp활성화.
// 폴리필은 필수 아님, 하지만 유용
const polyfill = () => {
RegExp.escape = RegExp.escape || function(s) {
return s.replace(/[-[\]\/{}()\*+?\.\\^$|]/g, '\\$&');
// 필요에 따라 확장
};
};
주요 포인트
- RegExp.escape()는 RegExp 연결을 위해 숫자/문자를 이스케이프하고, 공백은 예방 차원에서.
u플래그 없이는 오류가 가려짐; 있으면 파싱 시 SyntaxError 발생.- 직접 구현 함수는 구식: 폴리필과 함께 네이티브 버전으로 이전.
\cX피함—레거시; 명시적 코드 사용.- 공백 무시
x플래그는 실현 가능성 낮음.
— Editorial Team
아직 댓글이 없습니다.