31. 모던 자바스크립트 Deep Dive (RegExp)

⛅️ 정규 표현식이란?

  • 일정한 패턴을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어
  • 문자열을 대상으로 패턴 매칭 기능을 제공
  • 반복문과 조건문 없이 패턴을 정의하고 테스트하는 것으로 간단히 체크 가능
const tel = '010-1234-567팔';

// 정규식 리터럴로 휴대폰 전화번호 패턴 정의
const regExp = /^\d{3}-\d{4}-\d{4}$/;

regExp.test(tel); // false

⛅️ 정규 표현식의 생성

  • 정규 표현식 객체를 생성하기 위해선 정규 표현식 리터럴, RegExp 생성자 함수 사용 가능
  • 정규 표현식 리터럴은 패턴과 플래그로 구성됨
const target = 'Is this all there is?';

// 패턴: is
// 플래그: i => 대소문자를 구별하지 않고 검색한다
const regexp = /is/i;
const regexp2 = new RegExp(/is/i); // ES6
// new RegExp(/is/, 'i');
// new RegExp('is', 'i');

// test 메서드는 target 문자열에 대해 정규 표현식 regexp의 패턴을 검새갛여 매칭 결과를 불리언값으로 반환
regexp.test(target); // true

⛅️ RegExp 메서드

1. RegExp.prototype.exec

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

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

2. RegExp.prototype.test

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

regexp.test(target); // true

3. String.prototype.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']

⛅️ 플래그

  • 플래그는 정규 표현식의 검색 방식을 설정하기 위해 사용 함
  • 플래그는 옵션이므로 선택적으로 사용 가능
  • 순서와 상관없이 하나 이상의 플래그를 동시에 설정 가능
  • 플래그 종류
    • i : ignore case => 대소문자를 구변하지 않고 패턴 검색
    • g : global => 대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색
    • m : multi line => 문자열의 행이 바뀌더라도 패턴 검색을 계속 함
const target = 'Is this all there is?';

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

target.match(/is/i);
// ['Is',index:0, input:'Is this all there is?', groups:undefined]

target.match(/is/g);
// ['is', 'is']

target.match(/is/gi);
// ['Is','is','is']

⛅️ 패턴

  • 정규 표현식의 패턴은 문자열의 일정한 규칙을 표현하기 위해 사용됨
  • 정규 표현식의 플래그는 정규 표현식의 검색 방식을 설정하기 위해 사용됨
  • 문자열의 일정한 규칙을 표현하기 위해 사용됨
  • 패턴은 /로 열고 닫으며 문자열의 따옴표는 생략함
  • 특별한 의미를 가지는 메타문자 또는 기호로 표현 가능

1. 문자열 검색

  • RegExp 메서드를 사용하여 검색 대상 문자열과 정규 표현식의 매칭 결과를 구하면 검색이 수행됨
const target = 'Is this all there is?';

// 'is' 문자열과 매치하는 패턴, 대소문자 구별
const regExp1 = /is/;
// 'is' 문자열과 매치하는 패턴, 대소문자 구별 X
const regExp2 = /is/i;
// 'is' 문자열과 매치하는 패턴, 문자열 전체에서 검색, 대소문자 구별 X
const regExp3 = /is/gi;

2. 임의의 문자열 검색

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

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

3. 반복 검색

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

const regExp1 = /A{1,2}/g;
target.match(regExp1); // [A,AA,A,AA,A]

const regExp2 = /A{2}/g;
target.match(regExp2); // [AA, AA]

const regExp3 = /A{2,}/g;
target.match(regExp3); // [AA, AAA]

const regExp4 = /A+/g;
target.match(regExp4); // [A, AA, A, AAA]

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

4. OR 검색

  • |은 or의 의미를 갖는다.
  • [] 내의 문자는 or로 동작한다. 그 뒤에 +를 사용하면 앞선 패턴을 한번이상 반복
  • 범위를 지정하려면 [] 내에 - 를 사용
const target = 'A AA B BB Aa Bb';

const regExp1 = /A|B/g; // A 또는 B
target.match(regExp1); // [A,A,A,B,B,B,A,B]

const regExp2 = /A+|B+/g; // A가 한번 이상 또는 B가 한번 이상
target.match(regExp2); // [A,AA,B,BB,A,B]

const regExp3 = /[AB]+/g; // A가 한번 이상 또는 B가 한번 이상
target.match(regExp3); // [A,AA,B,BB,A,B]

const target2 = 'A AA BB ZZ Aa Bb';

const regExp4 = /[A-Z]+/g; // A~Z 가 한번 이상 반복되는 문자열 검색
target2.match(regExp4); // [A,AA,BB,ZZ,A,B]

const target = 'AA BB Aa Bb 12';
const regExp5 = /[A-Za-z]+/g; // A~Z 또는 a-z 가 한번 이상 반복되는 문자열 검색, 대소문자 구분 X
target2.match(regExp5); // [AA,BB,Aa,Bb]
const target = 'AA BB 12,345';

const regExp1 = /[0-9]+/g;
target.match(regExp1); // ['12','345']

const regexp2 = /[0-9,]+/g;
target.match(regExp2); // ['12,345']

// \d는 숫자를 의미함 === [0-9]
// \D는 숫자가 아닌 문자를 의미함
// \w는 알파벳,숫자,언더스코어를 의미함 === [A-Za-z0-9_]
// \W는 알파벳,숫자,언더스코어가 아닌 문자를 의미함

5. NOT 검색

  • []내의 ^는 not의 의미를 갖는다.
    • ex: [^0-9]는 숫자를 제외한 문자 === \D

6. 시작 위치로 검색

  • [] 밖의 ^는 문자열의 시작을 의미한다.
const target = 'https://donggyun.com';

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

7. 마지막 위치로 검색

  • $는 문자열의 마지막을 의미한다.
const target = 'https://donggyun.com';

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

⛅️ 자주 사용하는 정규표현식

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

  • 검색 대상 문자열이 http:// 또는 https://로 시작하는지 검사
  • [ ] 바깥의 ^는 문자열의 시작을 의미, ?는 앞선 패턴이 최대 한번(0번 포함) 이상 반복되는지 의미
  • ( )를 사용하여 or 조건을 묶을 수도 있음
const url = 'https://example.com';
const regExp = /^https?:\/\//;
const regExp2 = /^(http|https):\/\//;

2. 특정 단어로 끝나는지 검사

  • 검색 대상 문자열이 html로 끝나는지 검사
  • $는 문자열의 마지막을 의미함
const fileName = 'index.html';
const regExp = /html$/;

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

  • 검색 대상 문자열이 숫자로만 이루어진 문자열인지 검사
  • \d는 숫자를 의미하고 +는 앞선 패턴이 최소 한 번 이상 반복되는 문자열을 의미함
const target = '12345';
const regExp = /^\d+$/;

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

  • 검색 대상 문자열이 하나 이상의 공백으로 시작하는지 검사
  • \s는 여러가지 공백 문자(스페이스,탭 등) 을 의미한다.
const target = ' Hi!';
const regExp = /^[\s]+/;

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

  • 검색 대상 문자열이 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4~10자리인지 검사
  • {4,10}은 앞선 패턴이 최소 4번, 최대 10번 반복되는 문자열을 의미한다.
const id = 'abc123';
const regExp = /^[A-Za-z0-9]{4,10}$/;

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

const email = 'donggyun@gamil.com';
const regExp =
  /^[0-9A-Za-z]([-_\.]?[0-9a-zA-Z])*@[0-9A-Za-z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/;

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

const cellphone = '010-1234-5678';
const regExp = /^\d{3}-\d{3,4}-\d{4}$/;

8. 특수 문자 포함 여부 검사

const target = 'abc#123';
const regExp = /[^A-Za-z0-9]/gi/

📚 REFERENCE

  • 모던 자바스크립트 Deep Dive 31장 RegExp