본문 바로가기

Javascript

[모던 자바스크립트 Deep Dive] 28. RegExp

정규 표현식이란?

  • 일정한 패턴을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어
  • 문자열을 대상으로 패턴 매칭 기능을 제공 
  • 패턴 매칭 기능 : 특정 패턴과 일치하는 문자열을 검색하거나 추출 또는 치환할 수 있는 기능

 

정규 표현식의 생성

그림

  • 정규 표현식 리터럴과 RegExp 생성자 함수 사용 가능
  • 정규 표현식 리터럴은 패턴과 플래그로 구성

 

RegExp 메서드

1. RegExp.prototype.exec

  • 인수로 전달받은 문자열에 대해 정규 표현식의 패턴을 검사하여 매칭 결과를 배열로 반환
  • 매칭 결과가 없는 경우 null 반환
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

  • String 표준 빌트인 객체가 제공하는 match 메서드는 대상 문자열과 인수로 전달받은 정규 표현식과의 매칭 결과를 배열로 반환
const target = "Is this all there is?";
const regExp = /is/;

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

 

 

플래그

  • 정규 표현식의 검색 방법을 설정하기 위해 사용
  • 순서와 상관없이 하나 이상의 플래그를 동시에 설정 가능
플래그 의미 설명
i Ignore case 대소문자를 구별하지 않고 패턴 검색
g Global 대상 문자열 내에서 패턴과 일치하는 모든 문자열 전역 검색
m Multi line 문자열의 행이 바뀌더라도 패턴 검색을 계속

 

패턴

1. 문자열 검색

  • 검색 대상 문자열과 플래그를 생략한 정규 표현식의 매칭 결과를 구하면 대소문자를 구별하여 정규 표현식과 매치한 첫 번째 결과 반환
  • 플래그 i : 대소문자를 구별하지 않고 검색
  • 플래그 g : 전역 검색
const target = "Is this all there is?";
// 기본
target.match(/is/)  // ['is', index: 5, input: 'Is this all there is?', groups: undefined]

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

// 플래그 g
target.match(/is/g) //(2) ['is', 'is']

// 플래그 g 플래그 i
target.match(/is/gi)// (3) ['Is', 'is', 'is']

 

2. 임의의 문자열 검색

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

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

 

3. 반복 검색

  • 패턴{m,m} : 패턴이 최소 m 번 최대 n 번 반복되는 문자열 의미
  • 패턴{n} : 패턴이 n 번 반복되는 문자열
  • 패턴{n,} : 패턴이 최소 n번 이상 반복되는 문자열
  • 패턴+ : 패턴이 최소 한 번 이상 반복되는 문자열  
  • 패턴? : 최대 한 번 (0번 포함) 이상 반복되는 문자열
const target = 'A AA B BB Aa Bb AAA';

// A 가 최소 1번 최대 2 번 반복되는 문자열 전역 검색
target.match(/A{1,2}/g); // ['A', 'AA', 'A', 'AA', 'A']
// A 가 2번 반복되는 문자열 전역 검색
target.match(/A{2}/g);	// ['AA', 'AA']
// A가 최소 2번 이상 반복되는 문자열 전역 검색
target.match(/A{2,}/g);	//  ['AA', 'AAA']
// A가 한 번 이상 반복되는 문자열 전역 검색
target.match(/A+/g);	    // ['A', 'AA', 'A', 'AAA']

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

 

4. OR 검색

  • | : or
  • + 와 함께 사용하면 분해되지 않은 단어 레벨로 검색 가능
  • [] 내의 문자는 or 로 동작
  • [-] 범위 지정
  • \d : 숫자 
  • \D : 문자
  • \w : 알파벳, 숫자, 언더스코어
  • \W : 알파벳, 숫자, 언더스코어가 아닌 문자 
const target = "A AA B BB ZZ Aa Bb 12,345 _$%&";

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

// A 또는 B로 시작하는 문자열을 단어 레벨로 전역 검색
target.match(/A+|B+/g); // ['A', 'AA', 'B', 'BB', 'A', 'B']
target.match(/[AB]+/g); // ['A', 'AA', 'B', 'BB', 'A', 'B']

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

// 대소문자 구별하지 않고 알파벳 검사
target.match(/[A-Za-z]+/g); // ['A', 'AA', 'B', 'BB', 'ZZ', 'Aa', 'Bb']

// 숫자를 검색
target.match(/[0-9]+/g); // [ '12', '345' ]

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

// 숫자를 제외하고 블록 단위로 검색
target.match(/[\D]+/g); // ['A AA B BB ZZ Aa Bb ', ',', ' _$%&']

// 알파벳, 숫자, 언더스코어 검색
target.match(/[\w]+/g); // ['A', 'AA', 'B', 'BB', 'ZZ', 'Aa', 'Bb', '12', '345', '_']

// 알파벳, 숫자, 언더스코어 제외하고 검색
target.match(/[\W]+/g); // [' ', ' ', ' ', ' ', ' ', ' ', ' ', ',', ' ', '$%&']

 

5. NOT 검색

  • [] 내의 ^ 은 not 을 의미
  • [^0-9] : 숫자를 제외한 문자
  • [^A-Za-z0-9_] : \W
const target = "AA BB 12 Aa Bb";

// 한 번 이상 반복되는 숫자를 제외한 문자열 전역 검색
target.match(/[^0-9]+/g); // [ 'AA BB ', ' Aa Bb' ]

 

6. 시작 위치로 검색

  • [] 밖의 ^은 문자열의 시작을 의미
const target = "https://ehcichi.com";

/^https/.test(target); // false

 

7. 마지막 위치로 검색

  • $ : 문자열의 마지막
const target = "https://echichi.com";

/com$/.test(target); // true

 

자주 사용하는 정규표현식

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

const url = "https://example.com";

/^(http|https)?:\/\//.test(url);	// true

 

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

const fileName = "index.html";

/html$/.test(fileName);	// true

 

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

const target = '12345';

/^\d+$/.test(target);	// true

 

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

  • \s : 여러 가지 공백 문자
const target = " Hi";

/^[\s]+/.test(target);	// true

 

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

const id = 'abc213';
// 알파벳 또는 숫자로 시작하고 4 ~ 10 자리인지 검사
/^[A-Za-z0-9]{4,10}$/.test(id);	// true

 

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

const email = 'echichi@email.com';

/^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-z]{2,3}$/.test(email);	// true

// RFC 5322 규약
const regExp =
  /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;

 

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

const phone = 010-1234-5678;

/^\d{3}-\d{3,4}-\d{4}$/.test(phone); // true

 

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

const target = "abc<123";
// 알파벳과 숫자 이외의 문자
/[^A-Za-z0-9]/gi.test(target); // true