본문 바로가기
JavaScript/모던 자바스크립트 딥다이브

[JS] RegExp

by 김춘삼씨의 고양이 2024. 7. 22.

📌 정규 표현식이란?

  • 정규 표현식(Regular Expression): 일정한 패턴을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어(formal language)
  • 정규 표현식은 문자열을 대상으로 패턴 매칭 기능을 제공함
  • 패턴 매칭 기능: 특정 패턴과 일치하는 문자열을 검색하거나 추출 또는 치환할 수 있는 기능
  • 정규 표현식을 사용하면 반복문과 조건문 없이 패턴을 정의하고 테스트하는 것으로 간단히 체크할 수 있음

 

📌 정규 표현식의 생성

정규 표현식 리터럴

  • 정규 표현식 객체(RegExp 객체)를 생성하기 위해서는 정규 표현식 리터럴과 RegExp 생성자 함수를 사용할 수 있음
  • 정규 표현식 리터럴은 패턴과 플래그로 구성됨
  • RegExp 생성자 함수를 사용하여 RegExp 객체를 생성할 수도 있음
  • RegExp 생성자 함수를 사용하면 변수를 사용해 동적으로 RegExp 객체를 생성할 수 있음
const target = 'Is this all there is?';

// 정규 표현식 리터럴 사용
const regexp1 = /is/i;
regexp1.test(target); // -> true

// RegExp 생성자 함수 사용
const regexp2 = new RegExp(/is/i); // ES6
regexp2.test(target); // -> true

 

📌 RegExp 메서드

RegExp.prototype.exec

  • exec 메서드는 인수로 전달받은 문자열에 대해 정규 표현식의 패턴을 검색하여 매칭 결과를 배열로 반환함
  • 매칭 결과가 없는 경우 null을 반환함
  • exec 메서드는 문자열 내의 모든 패턴을 검색하는 g 플래그를 지정해도 첫 번째 매칭 결과만 반환함
const target = 'Is this all there is?';
const regexp = /is/;

regexp.exec(target);
// -> ['is', index: 5, input: 'Is this all ther is?', groups: undefined]

 

RegExp.prototype.test

  • test 메서드는 인수로 전달받은 문자열에 대해 정규 표현식의 패턴을 검색하여 매칭 결과를 불리언 값으로 반환함
const target = 'Is this all there is?';
const regexp = /is/;

regexp.test(target); // -> true

 

String.prototype.match

  • String 표준 빌트인 객체가 제공하는 match 메서드는 대상 문자열과 인수로 전달받은 정규 표현식과의 매칭 결과를 배열로 반환함
  • match 메서드는 g 플래그가 지정되면 모든 매칭 결과를 배열로 반환함
const target = 'Is this all there is?';
const regexp1 = /is/;
const regexp2 = /is/g;

target.match(regexp1);
// -> ['is', index: 5, input: 'Is this all there is?', groups: undefined]

target.match(regexp2); // -> ['is', 'is']

 

📌 플래그

  • 플래그(flag): 정규 표현식의 검색 방식을 설정하기 위해 사용함 
  • 플래그는 총 6개가 있음
  • 플래그는 옵션이므로 선택적으로 사용할 수 있으며, 순서와 상관없이 하나 이상의 플래그를 동시에 설정할 수도 있음
  • 어떠한 플래그를 사용하지 않은 경우 대소문자를 구별해서 패턴을 검색하고 문자열에 패턴 검색 매칭 대상이 1개 이상 존재해도 첫 번째 매칭한 대상만 검색하고 종료함
플래그 의미 설명
i ignore case 대소문자를 구별하지 않고 패턴을 검색함
g Global 대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색함
m Multi line 문자열의 행이 바뀌더라도 패턴 검색을 계속함

 

const target = 'Is this all there is?';

// target 문자열에서 is 문자열을 대소문자 구별하여 한 번만 검색
target.match(/is/);
// -> ['is', index: 5, input: 'Is this all there is?', groups: undefined]

// target 문자열에서 is 문자열을 대소문자 구별하지 않고 한 번만 검색
target.match(/is/i);
// -> ['Is', index: 0, input: 'Is this all there is?', groups: undefined]

// target 문자열에서 is 문자열을 대소문자 구별하여 전역 검색
target.match(/is/g);
// -> ['is', 'is']

// target 문자열에서 is 문자열을 대소문자 구별하지 않고 전역 검색
target.match(/is/ig);
// -> ['Is', 'is', 'is']

 

📌 패턴

  • 패턴(pattern): 문자열의 일정한 규칙을 표현하기 위해 사용
  • 패턴은 /로 열고 닫으며 문자열의 따옴표는 생략함
    따옴표를 포함하면 따옴표까지도 패턴에 포함되어 검색됨
  • 패턴은 특별한 의미를 가지는 메타문자 또는 기호로 표현할 수 있음

 

문자열 검색

  • 정규 표현식의 패턴에 문자 또는 문자열을 지정하면 검색 대상 문자열에서 패턴으로 지정한 문자 또는 문자열을 검색함
const target = 'Is this all there is?';

/* 'is' 문자열과 매치하는 패턴 */
// 플래그가 생략되었으므로 대소문자를 구별함
const regexp1 = /is/;
target.match(regexp1);
// -> ['is', index: 5, input: 'Is this all there is?', groups: undefined]

// 플래그가 i를 추가하면 대소문자를 구별하지 않음
const regexp2 = /is/i;
target.match(regexp2);
// -> ['Is', index: 0, input: 'Is this all there is?', groups: undefined]

// 플래그가 g를 추가하면 대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색함
const regexp3 = /is/ig;
target.match(regexp3); // -> ['Is', 'is', 'is']

 

임의의 문자열 검색

  • . 은 임의의 문자 한 개를 의미함
const target = 'Is this all there is?';

// 임의의 3자리 문자열을 대소문자를 구별하여 전역 검색
const regexp = /.../g;
target.match(regexp);
// -> ['Is ', 'thi', 's a', 'll ', 'the', 're ', 'is?']

 

반복 검색

  • {m,n}은 앞선 패턴이 최소 m번, 최대 n번 반복되는 문자열은 의미함
  • 콤마 뒤에 공백이 있으면 정상 동작하지 않음
const target = 'A AA B BB Aa Bb AAA';

// 'A'가 최소 1번, 최대 2번 반복되는 문자열을 전역 검색
const regexp = /A{1,2}/g;
target.match(regexp); // -> ['A', 'AA', 'A', 'AA', 'A']

 

  • {n}은 앞선 패턴이 n번 반복되는 문자열을 의미함 (즉, {n} = {n,n})
const target = 'A AA B BB Aa Bb AAA';

// 'A'가 2번 반복되는 문자열을 전역 검색
const regexp = /A{2}/g;
target.match(regexp); // -> ['AA', 'AA']

 

  • {n,}은 앞선 패턴이 최소 n번 이상 반복되는 문자열을 의미함
const target = 'A AA B BB Aa Bb AAA';

// 'A'가 최소 2번 이상 반복되는 문자열을 전역 검색
const regexp = /A{2,}/g;
target.match(regexp); // -> ['AA', 'AAA']

 

  • +는 앞선 패턴이 최소 한 번 이상 반복되는 문자열을 의미함 (즉, + = {1,})
const target = 'A AA B BB Aa Bb AAA';

// 'A'가 최소 한 번 이상 반복되는 문자열을 전역 검색
const regexp = /A+/g;
target.match(regexp); // -> ['A', 'AA', 'A', 'AAA']

 

  • ?는 앞선 패턴이 최대 한 번(0번 포함) 이상 반복되는 문자열을 의미함 (즉, ? = {0,1})
const target = 'color colour';

// 'colo' 다음 'u'가 최대 한 번(0번 포함) 이상 반복되고 'r'이 이어지는 문자열을 전역 검색
const regexp = /colou?r/g;
target.match(regexp); // -> ['color', 'colour']

 

OR 검색

  • |은 or의 의미를 가짐
  • 분해되지 않은 단어 레벨로 검색하기 위해서는 +를 함께 사용해야 함
  • [] 내의 문자는 or로 동작하며, 그 뒤에 +를 사용하면 앞선 패턴을 한 번 이상 반복함
const target = 'A AA B BB Aa Bb AAA';

// 'A' 또는 'B'를 전역 검색
const regexp1 = /A|B/g;
target.match(regexp1);
// -> ['A', 'A', 'A', 'B', 'B', 'B', 'A', 'B', 'A', 'A', 'A']

// 'A' 또는 'B'가 한 번 이상 반복되는 문자열을 전역 검색
const regexp2 = /A+|B+/g;
target.match(regexp2);
// -> ['A', 'AA', 'B', 'BB', 'A', 'B', 'AAA']

// 'A' 또는 'B'가 한 번 이상 반복되는 문자열을 전역 검색
const regexp3 = /[AB]+/g;
target.match(regexp3);
// -> ['A', 'AA', 'B', 'BB', 'A', 'B', 'AAA']

 

  • 범위를 지정하려면 [] 내에 -를 사용함
const target1 = 'A AA BB ZZ Aa Bb';
const target2 = 'AA BB Aa Bb 12';
const target3 = 'AA BB 12,345';

// 'A' ~ 'Z'가 한 번 이상 반복되는 문자열을 전역 검색
const regexp1 = /[A-Z]+/g;
target1.match(regexp1); // -> ['A', 'AA', 'BB', 'ZZ', 'A', 'B']

// 'A' ~ 'Z' 또는 'a' ~ 'z'가 한 번 이상 반복되는 문자열을 전역 검색
const regexp2 = /[A-Za-z]+/g;
target2.match(regexp2); // -> ['AA', 'BB', 'Aa', 'Bb']

// '0' ~ '9'가 한 번 이상 반복되는 문자열을 전역 검색
const regexp3 = /[0-9]+/g;
target3.match(regexp3); // -> ['12', '345']

// '0' ~ '9' 또는 ','가 한 번 이상 반복되는 문자열을 전역 검색
const regexp4 = /[0-9,]+/g;
target3.match(regexp4); // -> ['12,345']

 

  • \d는 숫자를 의미함 (즉, \d = [0-9])
  • \D는 숫자가 아닌 문자를 의미함
const target = 'AA BB 12,345';

// '0' ~ '9' 또는 ','가 한 번 이상 반복되는 문자열을 전역 검색
const regexp1 = /[\d,]+/g;
target.match(regexp1); // -> ['12,345']

// '0' ~ '9'가 아닌 문자(숫자가 아닌 문자) 또는 ','가 한 번 이상 반복되는 문자열을 전역 검색
const regexp2 = /[\D,]+/g;
target.match(regexp2); // -> ['AA BB ', ',']

 

  • \w는 알파벳, 숫자, 언더스코어를 의미함 (즉, \w = [A-Za-z0-9_])
  • \W는 알파벳, 숫자, 언더스코어가 아닌 문자를 의미함
const target = 'AA BB 12,345 _$%&';

// 알파벳, 숫자, 언더스코어, ','가 한 번 이상 반복되는 문자열을 전역 검색
const regexp1 = /[\w,]+/g;
target.match(regexp1); // -> ['AA', 'BB', '12,345', '_']

// 알파벳, 숫자, 언더스코어가 아닌 문자 또는 ','가 한 번 이상 반복되는 문자열을 전역 검색
const regexp2 = /[\W,]+/g;
target.match(regexp2); // -> [' ', ' ', ',', ' ', '$%&']

 

NOT 검색

  • [...] 내의 ^은 not의 의미를 가짐
  • [0-9]와 같은 의미의 \d와 반대로 동작하는 \D는 [^0-9]와 같음
  • [A-Za-z0-9_]와 같은 의미의 \w와 반대로 동작하는 \W는 [^A-Za-z0-9_]와 같음
const target = 'AA BB 12 Aa Bb';

// 숫자를 제외한 문자열을 전역 검색
const regexp = /[^0-9]+/g;
target.match(regexp); // -> ['AA BB ', ' Aa Bb']

 

시작 위치로 검색

  • [...] 밖의 ^은 문자열의 시작을 의미함
const target = 'https://www.naver.com';

// 'https'로 시작하는지 검사
const regexp = /^https/g;
regexp.test(target); // -> true

 

마지막 위치로 검색

  • $는 문자열의 마지막을 의미함
const target = 'https://www.naver.com';

// 'com'으로 끝나는지 검사
const regexp = /com$/g;
regexp.test(target); // -> true

 

📌 자주 사용하는 정규 표현식

특정 단어로 시작하는지 검사

const target = 'https://www.naver.com';

// 'http://' 또는 'https://'로 시작하는지 검사
const regexp1 = /^https?:\/\//;
regexp1.test(target); // -> true

const regexp2 = /^(http|https):\/\//;
regexp2.test(target); // -> true

 

특정 단어로 끝나는지 검사

const target = 'index.html';

// 'html'로 끝나는지 검사
const regexp = /html$/g;
regexp.test(target); // -> true

 

숫자로만 이루어진 문자열인지 검사

const target = '12345';

// 숫자로만 이루어진 문자열인지 검사
const regexp = /^\d+$/;
regexp.test(target); // -> true

 

하나 이상의 공백으로 시작하는지 검사

  • \s는 여러 가지 공백 문자(스페이스, 탭 등)를 의미함 (즉, \s = [\t\r\n\v\f])
const target = ' Hi!';

// 하나 이상의 공백으로 시작하는지 검사
const regexp = /^[\s]+/;
regexp.test(target); // -> true

 

아이디로 사용 가능한지 검사

const target = 'abc1234';

// 검색 대상 문자열이 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4 ~ 10자리인지 검사
const regexp = /^[A-Za-z0-9]{4,10}$/;
regexp.test(target); // -> true

 

메일 주소 형식에 맞는지 검사

const target = 'test123@gmail.com';

const regexp = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/;
regexp.test(target); // -> true

 

핸드폰 번호 형식에 맞는지 검사

const target = '010-1234-5678';

const regexp = /^\d{3}-\d{3,4}-\d{4}$/;
regexp.test(target); // -> true

 

특수 문자 포함 여부 검사

  • 특수 문자는 A-Za-z0-9 이외의 문자
const target = 'abc#123';

// 특수 문자 포함 여부 검사
const regexp1 = /[^A-Za-z0-9]/gi;
regexp1.test(target); // -> true

// 특수 문자를 선택적으로 검사
const regexp2 = /[\{\}\[\]\/?.,;:|\)*~`!^\-_+<>@\#$%&\\\=\(\'\"]/gi;
regexp2.test(target); // -> true

// 특수 문자 제거
target.replace(regexp1, ''); // -> 'abc123'

 

 

 

참고문헌 및 출처 : 모던 자바스크립트 Deep Dive (이웅모)

'JavaScript > 모던 자바스크립트 딥다이브' 카테고리의 다른 글

[JS] 7번째 데이터 타입 Symbol  (0) 2024.07.27
[JS] String  (0) 2024.07.24
[JS] Date  (0) 2024.07.22
[JS] Math  (2) 2024.07.19
[JS] Number  (0) 2024.07.17

댓글