검색 기능을 만들다 보면 사용자가 입력한 문자열로 정규식을 짜야 할 때가 있다. 하이라이트 처리라든가, 단어 단위 매칭이라든가.
문제는 사용자 입력을 그대로 new RegExp()에 넣으면 터진다는 거다. 누가 검색창에 a.b를 쳤다고 해보자.
const keyword = 'a.b';
const re = new RegExp(keyword);
re.test('axb'); // true ← 어? a.b를 찾았는데 axb가 걸린다
.이 "아무 글자 하나"로 해석되니까 의도와 다르게 매칭된다. 더 심하면 ( 하나만 들어와도 SyntaxError: Invalid regular expression으로 아예 죽는다. 사용자가 괄호 하나 쳤다고 앱이 터지는 건 좀 곤란하다.
예전엔 이렇게 했다
그래서 다들 MDN에서 복붙한 이 정규식을 하나씩 들고 다녔다.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
동작은 하는데, 저 문자 클래스 안에 뭐가 빠졌는지 매번 불안했다. 프로젝트마다 복사해 다니는 것도 찜찜하고.
이제 내장 함수가 있다
ES2025에 RegExp.escape()가 정식으로 들어왔다. 입력 문자열의 정규식 특수문자를 전부 이스케이프한 새 문자열을 돌려준다.
const keyword = 'a.b';
const re = new RegExp(RegExp.escape(keyword));
re.test('axb'); // false
re.test('a.b'); // true ← 이제 문자 그대로 찾는다
괄호가 들어와도 안 터진다.
RegExp.escape('price (USD)'); // 'price\\ \\(USD\\)'
실제 검색 하이라이트에 쓰면 이런 모양이다. g, i 같은 플래그는 두 번째 인자로 평소처럼 붙이면 된다.
function highlight(text, query) {
if (!query) return text;
const re = new RegExp(RegExp.escape(query), 'gi');
return text.replace(re, (m) => `<mark>${m}</mark>`);
}
highlight('C++ 과 C#', 'c++');
// 'C++ 과 C#'에서 'C++'만 정확히 하이라이트된다
예전 같으면 c++의 + 때문에 매칭이 엉망이 됐을 텐데, 이제 신경 안 써도 된다.
정리
- 사용자 입력을 정규식에 넣기 전엔 무조건
RegExp.escape()를 거쳐라. 안 하면 오동작 아니면 크래시다. - 2026년 기준 최신 Chrome·Firefox·Safari엔 들어왔지만, 구형 브라우저나 서버 런타임이 섞여 있으면 지원 여부를 먼저 확인하자. 없으면
core-js폴리필이나 위의 수동escapeRegExp를 폴백으로 두면 된다. - 참고로 이건 입력을 "문자 그대로" 찾게 만드는 용도다. 사용자가 와일드카드를 쓰게 하고 싶다면 이스케이프가 아니라 별도 파싱이 필요하다.
검색어 하이라이트 하나 만드는 데 정규식 특수문자 표를 더 이상 외우지 않아도 된다는 게 생각보다 편하다.