Programming/JavaScript

JavaScript 에서 정규식 활용하는 방법들

고고마코드 2022. 8. 11. 17:30
반응형

정규식 플래그에 관한 내용이 궁금하다면 아래 글을 참고해 주세요.
정규 표현식/정규식(RegExp) 플래그(Flag) 자세하게 알아보자!


정규식 패턴에 관한 내용이 궁금하다면 아래 글을 참고해 주세요.
예제로 정리한 정규식 패턴


1. Javascript에서 정규식을 만드는 두 가지 방법

RegExp 객체

const regExp = new RegExp(/reg/, 'g');

new RegExp(/pattern/, 'flag')

RegExp 객체의 생성자를 호출해 정규 표현식을 만듭니다.

패턴과 플래그에 대한 자세한 내용은 다루지 않습니다. 해당 내용은 상단의 링크를 참고하세요.

정규 표현식 리터럴

const regExp = /reg/g;

/pattern/flag

정규 표현식 리터럴 방식으로 만듭니다.

두 방법은 차이가 있습니다.

RegExp 객체의 생성자로 호출하면 정규식은 호출할 때 런타임에 컴파일 됩니다. 그래서 정규식을 동적으로 사용해야 하는 경우에 RegExp 객체로 생성자를 호출하고,

리터럴 방식은 스크립트를 불러올 때 컴파일 됩니다. 주로 정규식이 바뀔 일이 없는 경우 리터럴을 사용하면 좋습니다.


2. RegExp 객체의 메소드

RegExp.exec()

문자열에서 일치하는 부분을 탐색 일치하면 array, 일치하지 않으면 null 반환

  • exec() 예제
var input = `1 -2 3 -4 5 -6`;
var regExp = /\d+/g;
var output = [];
while ((search = regExp.exec(input)) !== null) {
  output.push(search[0]);
}

exec()는 전역 플래그(g)로 설정하더라도 일치하는 패턴 한 개씩만 탐색합니다.

일치하는 부분을 찾으면 RegExp 객체의 lastIndex 속성을 업데이트하고 값을 반환하기 때문입니다.

만약 while로 반복하지 않았다면 '1'만 반환하고 종료되었을 것입니다.

만약 탐색이 실패해 false가 반환된다면 lastIndex 속성도 0으로 초기화 됩니다.

  • lastIndex 이해를 위한 예제 - 1
var input = `1 -2 3 -4 5 -6`;
var regExp = /\d+/g;
console.log('regExp.lastIndex: '+regExp.lastIndex); 
var output = regExp.exec(input);
console.log('regExp.lastIndex: '+regExp.lastIndex);
0
1

  • lastIndex 이해를 위한 예제 - 2
var input = `1 -2 3 -4 5 -6`;
var regExp = /\d+/g;
var output = [];
while ((search = regExp.exec(input)) !== null) {
  output.push(search[0]);
  console.log('regExp.lastIndex: '+regExp.lastIndex);
}
console.log('regExp.lastIndex: '+regExp.lastIndex);
1
4
6
9
11
14
0

lastIndex 이해를 위한 예제 (1, 2)

RegExp.test()

문자열에서 일치하는 부분을 탐색
일치하면 true, 일치하지 않으면 false 반환

  • test() 예제
// test() - 1
var input = `1 -2 3 -4 5 -6`;
var regExp = /\d+/g;
var output = regExp.test(input);

// test() - 2
var input = `1 -2 3 -4 5 -6`;
var regExp = /0/g;
var output = regExp.test(input);


3. String 객체의 메소드

String.match()

문자열에서 일치하는 패턴을 배열에 담아 반환합니다.

  • match() 예제
// match() - 1
var input = `1 -2 3 -4 5 -6`;
var regExp = /\d+/g;
var output = input.match(regExp);

// match() - 2
var input = `1 -2 3 -4 5 -6`;
var regExp = /0+/g;
var output = input.match(regExp);

정규식에서 숫자만 구분하다보니 음수는 모두 빠졌네요.

match() - 1 이 음수까지 제대로 포함되도록 정규식 패턴을 살짝 수정할게요.

// match() - 1
var input = `1 -2 3 -4 5 -6`;
var regExp = /(-?\d)+/g;
var output = input.match(regExp);

정규식 패턴에 대해서 자세히 알고 싶다면 상단의 "예제로 정리한 정규식 패턴" 글을 참고해 주세요.

String.matchAll()

문자열에서 일치하는 패턴을 패턴을 담은 배열을 반환합니다.

이 때 일치하는 패턴의 각 캡처그룹도 모두 배열에 같이 담아서 반환합니다.

  • matchAll() 예제
// matchAll()
var input = `test`;
var regExp = /(t)(e)(st)/g;
var output = [...input.matchAll(regExp)];

(t) (e) (st) 3개의 캡처그룹으로 패턴을 만들었습니다.

패턴에 일치하는 'test', 각 캡처그룹의 패턴인 't', 'e', 'st' 가 배열에 담아 반환되었습니다.

String.search()

문자열에서 일치하는 패턴이 있는지 확인합니다. 해당 패턴이 시작하는 인덱스를 반환합니다.

패턴이 없다면 -1을 반환합니다.

  • search() 예제
// search()
var input = 'Now is the time to study regular expressions.';
var regExp = /t/g;
var output = input.search(regExp);

주의할 점

문자열의 인덱스는 0부터 시작입니다.

여러개 있어도 먼저 찾은 인덱스의 번호만 반환합니다.

예제에서 보다시피 여러개의 't'가 있지만 제일 빠른 인덱스 번호인 7만 반환되었습니다.

String.replace()

제일 많이 쓰이는 치환 메소드입니다.

문자열에서 일치하는 패턴을 원하는 문자열로 치환할 수 있습니다.

치환한 문자열을 반환합니다.

  • replace() 예제1
// replace() - 1
var input = 'Now is the time to study regular expressions.';
var regExp = /(t)(\w)(\w)/g;
var output = input.replace(regExp, "***");

패턴을 지정하긴 했지만 만약 (t) 와 마지막 (\w) 의 위치를 바꾸고 싶으면 어떻게 해야 할까요?

  • replace() 예제2
// replace() - 2
var input = 'Now is the time to study regular expressions.';
var regExp = /(t)(\w)(\w)/g;
var output = input.replace(regExp, "$3$2$1");

$를 사용하면 그룹 캡처의 번호로 패턴을 역참조 할 수 있어요.

그룹캡처 순서대로 $1, $2, ... 번호로 사용할 수 있습니다.

이해하기 쉽게 무조건 전역플래그(g)를 사용했었는데, replace()는 전역플래그가 없으면 먼저 찾는 패턴만 치환해요.

예제1에서 전역플래그(g)만 제외해볼게요.

  • replace() 예제3
// replace() - 3
var input = 'Now is the time to study regular expressions.';
var regExp = /(t)(\w)(\w)/;
var output = input.replaceAll(regExp, "***");

먼저 찾은 'the' 만 치환된 것을 확인할 수 있습니다.

String.replaceAll()

replaceAll()은 정규식에 전역플래그(g)가 포함된 replace() 와 같습니다.

💣주의할 점은 전역플래그(g)가 반드시 있어야 해요! 없으면 오류납니다!

  • replaceAll() 예제
// replaceAll()
var input = 'Now is the time to study regular expressions.';
var regExp = /(t)(\w)(\w)/g;
var output = input.replaceAll(regExp, "***");

String.split()

split은 특정 문자열을 기준으로 문자열을 쪼개 배열로 반환합니다.

근데 split은 조금 특이한 점이 있어요.

그룹캡처로 묶은 부분을 모두 자르는 대상으로 삼아요.

예제 2개를 통해 비교설명할게요.

// split() - 1
var input = 'Now is the time to study regular expressions.';
var regExp = /(t)(\w)(\w)/g;
var output = input.split(regExp);

// split() - 2
var input = 'Now is the time to study regular expressions.';
var regExp = /(t\w\w)/g;
var output = input.split(regExp);

차이가 바로 보이죠?

그룹을 모두 합쳐 하나의 패턴으로 자르지 않고 각 그룹별로 자르는 것을 확인할 수 있습니다.

(물론 여러 그룹을 두면서 자를 만큼 복잡한 split을 사용하지는 않을 것 같기는 해요...^^)


4. 참고자료

  1. developer.mozilla.org

반응형