최근에 정규식을 사용하면서 발생한 이슈를 해결하면서 정리한 내용입니다. 에러의 원인을 알 수 있을 정도의 정규식 문법을 알아보고, 이슈를 해결하는 방법을 정리해보았습니다.
목차
펼치기
정규식(RegExp)이란?
정규식(Regular Expression)은 문자열을 처리하는 방법 중 하나로, 문자열의 검색, 치환, 분리 등을 할 때 사용합니다. 정규식은 문자열의 패턴을 정의하는데 사용되며, 이를 통해 문자열을 검색하거나 치환할 수 있습니다.
문법
정규식은 /
로 시작하고 끝나며, 문자열을 검색할 때 사용됩니다. 정규식은 문자열의 패턴을 정의하는데 사용되며, 이를 통해 문자열을 검색하거나 치환할 수 있습니다.
1. 문자열 검색
test()
: 문자열이 정규식에 맞는지 검사합니다.
const regex = /hello/;
console.log(regex.test("hello")); // true
console.log(regex.test("world")); // false
exec()
: 정규식과 일치하는 문자열을 검색합니다. test()와 달리 일치하는 문자열을 반환합니다.- index: 일치하는 문자열의 시작 위치
- input: 검색 대상 문자열
- groups: 그룹에 일치하는 문자열
const regex = /hello/;
console.log(regex.exec("hello world"));
// ["hello", index: 0, input: "hello world", groups: undefined]
2. 플래그(Flag)
i
: 대소문자를 구분하지 않습니다.g
: 전역 검색을 수행합니다.m
: 여러 줄 검색을 수행합니다.
const regex = /hello/gi;
console.log("Hello world".match(regex)); // ["Hello"]
3. 문자 클래스
[]
: 문자 클래스를 정의합니다.
const regex = /[a-z]/;
console.log(regex.test("hello")); // true
console.log(regex.test("123")); // false
4. 이스케이프
\
: 이스케이프 문자를 사용합니다.
const regex = /\./;
console.log(regex.test("hello.")); // true
5. 퀀티파이어, 반복
{n}
: n회 반복되는 문자와 일치합니다.{n,}
: n회 이상 반복되는 문자와 일치합니다.{n,m}
: n회 이상, m회 이하 반복되는 문자와 일치합니다.*
: 0회 이상 반복되는 문자와 일치합니다.+
: 1회 이상 반복되는 문자와 일치합니다.?
: 0회 또는 1회 반복되는 문자와 일치합니다.
const regex = /l{2}/;
console.log(regex.test("hello")); // true
6. 앵커
^
: 문자열의 시작과 일치합니다.$
: 문자열의 끝과 일치합니다.- ‘\b’: 단어 경계와 일치합니다.
- ‘\B’: 단어 경계가 아닌 부분과 일치합니다.
const regex = /^hello/;
console.log(regex.test("hello world")); // true
const regex = /world$/;
console.log(regex.test("hello world")); // true
const regex = /\bhello\b/;
console.log(regex.test("hello world")); // true
const regex = /\Bhello\B/;
console.log(regex.test("hello world")); // false
7. 문자열 대체
$$
: ”$“를 삽입합니다.$&
: 일치된 부분 문자열을 삽입니다.- $`: 일치하는 부분 문자열 앞에 있는 문자열 부분을 삽입합니다.
$'
: 일치하는 부분 문자열 뒤에 있는 문자열 부분을 삽입합니다.$n
: n번째(1로부터 시작하는) 캡처 그룹을 삽입합니다. 여기서 n은 100보다 작은 양의 정수입니다.$<Name>
: Name이 그룹 이름인 명명된 캡처 그룹을 삽입합니다.
const regex = /hello/;
console.log("hello world".replace(regex, "world")); // world world
const regex = /(\w+)\s(\w+)/;
console.log("hello world".replace(regex, "$2 $1")); // world hello
const regex = /(\w+)\s/;
console.log("hello world".replace(regex, "$'")); // worldworld
이슈
만약에 정규식의 패턴을 사용자의 입력을 받아서 사용한다면, 입력한 패턴의 타입이 스트링인지, 정규식인지 구분해서 입력받아야 합니다. 만약에 사용자의 입력이 스트링이라면, 이스케이프 처리를 해주어야 합니다. 아래의 예제는 MDN에서 제공하는 이스케이프 처리를 해주는 코드입니다.
const userInput = "hello.";
const inputType = 'string';
const escapedInput = userInput.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const pattern = inputType === 'string' ? escapedInput : userInput;
const regex = new RegExp(pattern);
console.log(regex.test("hellon")); // true
추가로 사용자의 입력을 new RegExp()
에 넣어서 정규식을 생성할 때, 사용자의 입력 값이 유효한 정규식인지 확인해야 합니다. 만약에 유효한 정규식이 아니라면, 에러가 발생할 수 있습니다.
const userInput = "[hello.";
try {
const regex = new RegExp(userInput);
console.log(regex.test("hello."));
} catch (e) {
console.error(e);
// Error: Invalid regular expression: missing /
}
escape 하지 않는 경우
escape 하는 경우
결론
사용자의 입력을 받아 정규식을 사용할 때는 입력받은 패턴의 타입이 스트링인지, 정규식인지 구분해서 처리해야 합니다. 만약에 스트링이라면, 이스케이프 처리를 해주어야 합니다. 또한, 사용자의 입력이 유효한 정규식인지 확인해야 합니다. 이를 통해 에러를 방지하고, 안전하게 사용할 수 있습니다.