[딥다이브] 31장_RegExp

이말감·2022년 10월 3일
0

딥다이브

목록 보기
8/10

모던 자바 스크립트 Deep Dive 를 공부하며 정리하는 글을 또 정리하며 이해하는 글입니다.


1.정규 표현식이란?

  • 정규 표현식(regular expression)은 일정한 패턴을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어
  • 정규 표현식은 자바스크립트의 고유 문법이 아니며, 대부분의 프로그래밍 언어와 코드 에디터에 내장되어 있음.

패턴 매칭 기능

  • 정규 표현식은 문자열을 대상으로 패턴 매칭 기능을 제공한다.
    • 패턴 매칭 기능이란 특정 패턴과 일치하는 문자열을 검색하거나 추출 또는 치환할 수 있는 기능을 말한다.

예시

  • 휴대폰 전화번호는 "숫자 3개 + '-' + 숫자 4개 + '-' + 숫자 4개"라는 일정한 패턴이 있다.
// 사용자로부터 입력받은 휴대폰 전화번호
const tel = '010-1234-567팔';

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

// tel이 휴대폰 전화번호 패턴에 매칭하는지 테스트(확인)한다.
regExp.test(tel); // -> false
  • 정규표현식을 사용하면 반복문과 조건문 없이 패턴을 정의하고 테스트하는 것으로 간단히 체크할 수 있다.
  • 다만 정규 표현식은 주석이나 공백을 허용하지 않고 여러 가지 기호를 혼합하여 사용하기 때문에 가독성이 좋지 않다.

2.정규 표현식의 생성

  • 정규 표현식 객체(RegExp 객체)를 생성하기 위해서는 정규 표현식 리터럴과 RegExp 생성자 함수를 사용할 수 있다.

정규 표현식 리터럴

  • 정규 표현식 리터럴은 패턴과 플래그로 구성된다.
const target = 'Is this all there is?';

// 패턴 : is
// 플래그 : i => 대소문자를 구별하지 않고 검색한다.
const regexp = /is/i;

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

RegExp 생성자 함수

  • RegExp 생성자 함수를 사용하여 RegExp 객체를 생성할 수도 있다.
/**
* pattern : 정규 표현식의 패턴
* flags : 정규 표현식의 플래그(g, i, m, u, y)
*/
new RegExp(pattern[, flags])
const target = 'Is this all there is?";
const regexp = new RegExp(/is/i); // ES6
// const regexp = new RegExp(/is/, 'i');
// const regexp = new RegExp('is', 'i');

regexp.test(target); // true
  • RegExp 생성자 함수를 사용하면 변수를 사용해 동적으로 RegExp 객체를 생성할 수 있다.
const count = (str, char) => (str.match(new RegExp(char, 'gi')) ?? []).length;
                              
count('Is this all there is?', 'is'); // 3
count('Is this all there is?', 'xx'); // 0

3. RegExp 메서드

3.1 RegExp.prototype.exec

  • 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]
  • exec 메서드는 문자열 내의 모든 패턴을 검색하는 g 플래그를 지정해도 첫 번째 매칭 결과만 반환하므로 주의해야 함

3.2 RegExp.prototype.test

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

regExp.test(target); // true

3.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]
  • exec 메서드는 문자열 내의 모든 패턴을 검색하는 g 플래그를 지정해도 첫 번째 매칭 결과만 반환한다.
  • 하지만 String.prototype.match 메서드는 g 플래그가 지정되면 모든 매칭 결과를 배열로 반환한다.
const target = 'Is this all there is?';
const regExp = /is/g;

target.match(regExp); // -> ["is", "is"]

4.플래그

  • 패턴과 함께 정규 표현식을 구성하는 플래그는 정규 표현식의 검색 방식을 설정하기 위해 사용한다.

i

  • ignore case
  • 대소문자를 구별하지 않고 패턴을 검색한다.

g

  • Global
  • 대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색한다.
    • 대소문자를 구별하여 전역 검색

m

  • Multi line
  • 문자열의 행이 바뀌더라도 패턴 검색을 계속한다.
  • 플래그는 옵션이므로 선택적으로 사용할 수 있으며, 순서와 상관없이 하나 이상의 플래그를 동시에 설정할 수도 있다.
  • 어떠한 플래그를 사용하지 않은 경우 대소문자를 구별하여 패턴을 검색한다.
  • 문자열에 패턴 검색 매칭 대상이 1개 이상 존재해도 첫 번째 매칭한 대상만 검색하고 종료한다.
const target = 'Is this all there is?';

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

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

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

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

5.패턴

  • 정규 표현식은 패턴과 플래그로 구성된다.
  • 정규 표현식의 패턴은 문자열의 일정한 규칙을 표현하기 위해 사용하며, 정규 표현식의 플래그는 정규 표현식의 검색 방식을 설정하기 위해 사용한다.
  • 패턴은 /로 열고 닫으며 문자열의 따옴표는 생략한다.
    • 따옴표를 포함하면 따옴표까지도 패턴에 포함되어 검색된다.
  • 패턴은 특별한 의미를 가지는 메타문자 또는 기호로 표현할 수 있다.
  • 어떤 문자열 내에 패턴과 일치하는 문자열이 존재할 때 '정규 표현식과 매치한다'고 표현한다.

5.1 문자열 검색

  • 정규 표현식의 패턴에 문자 또는 문자열을 지정하면 검색 대상 문자열에서 패턴으로 지정한 문자 또는 문자열을 검색한다.
  • 물론 정규 표현힉을 생성하는 것만으로 검색이 수행되지는 않는다.
  • RegExp 메서드를 사용하요 검색 대상 문자열과 정규 표현식의 매칭 결과를 구하면 검색이 수행된다.
  • 검색 대상 문자열과 플래그를 생략한 정규 표현식의 매칭 결과를 구하면 대소문자를 구별하여 정규 표현식과 매치한 첫 번째 결과만 반환한다.
const target = 'Is this all there is?';

// 'is' 문자열과 매치하는 패턴. 플래그가 생략되었으므로 대소문자를 구별한다.
const regExp = /is/;

// target과 정규 표현식이 매치하는지 테스트한다.
regExp.test(target); // true

// target과 정규 표현식이 매치하는지 테스트한다.
regExp.match(regExp);
// -> ["is", index : 5, input : "Is this all there is?", groups : undefined]
  • 대소문자를 구별하지 않고 검색하려면 플래그 i를 사용한다.
const target = 'Is this all there is?';

// 'is' 문자열과 매치하는 패턴. 플래그 i를 추가하면 대소문자를 구별하지 않는다.
const regExp = /is/i;

target.match(regExp);
// -> ["Is", index : 0, input : "Is this all there is?", groups : undefined]
  • 검색 대상 문자열 내에서 패턴과 매치하는 모든 문자열을 전역 검색하려면 플래그 g를 사용한다.
const target = 'Is this all there is?';

// 'is' 문자열과 매치하는 패턴
// 플래그 g를 추가하면 대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색한다.
const regExp = /is/ig;

target.match(regExp); // -> ["Is", "is", "is"]

5.2 임의의 문자열 검색

  • . 은 임의의 문자 한 개를 의미한다.
  • 문자의 내용은 무엇이든 상관없다.
const target = 'Is this all there is?';

// 임의의 3자리 문자열을 대소문자를 구별하여 전역 검색한다.
const regExp = /.../g;

target.match(regExp); 
// -> ["is ", "thi", "s a", "ll ", "the", "re ", "is?"];

5.3 반복 검색

  • {m,n}은 앞선 패턴(다음 예제의 경우 A)이 최소 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'가 최소 한 번 이상 반복되는 문자열 ('A, 'AA', 'AAA', ...)을 전역 검색한다.
const regExp = /A+/g;

target.match(regExp); // -> ["A", "AA", "A", "AAA"]
  • ?는 앞선 패턴이 최대 한 번(0번 포함) 이상 반복되는 문자열을 의미한다.
  • 즉, ?는 {0,1}과 같다.
  • 다음 예제의 경우 /colou?r/는 다음 'u'가 최대 한 번(0번 포함) 이상 반복되고 'r'이 이어지는 문자열 'color', 'colour'와 매치한다.
const target = 'color colour';

// 'colo' 다음 'u'가 최대 한 번(0번 포함) 이상 반복되고 'r'이 이어지는
// 문자열 'color', 'colour'를 전역 검색한다.

const regExp = /colou?r/g;
target.match(regExp); // -> ["color", "colour"]

5.4 OR 검색

  • |은 or의 의미를 갖는다.
  • 다음 예제의 /A|B/는 'A' 또는 'B'를 의미한다.
const target = 'A AA B BB Aa Bb AAA';

// 'A' 또는 'B'를 전역 검색한다.
const regExp = /A|B/g;

target.match(regExp); // ["A", "A", "A", "B", "B", "B", "A", "B"]
  • 분해되지 않은 단어 레벨로 검색하기 위해서는 +를 함께 사용한다.
const target = 'A AA B BB Aa Bb AAA';

// 'A' 또는 'B'가 한 번 이상 반복되는 문자열을 전역 검색한다.
// 'A', 'AA', 'AAA', ... 또는 'B', 'BB', 'BBB', ...
const regExp = /A+|B+/g;

target.match(regExp); // -> ["A", "AA", "B", "BB", "A", "B"]
  • 위 예제는 패턴을 or로 한 번 이상 반복하는 것인데 이를 간단히 표현하면 다음과 같다.
  • [] 내의 문자는 or로 동작하고, 그 뒤에 +를 사용하면 앞선 패턴을 한 번 이상 반복한다.
const target = 'A AA B BB Aa Bb AAA';

// 'A' 또는 'B'가 한 번 이상 반복되는 문자열을 전역 검색한다.
// 'A', 'AA', 'AAA', ... 또는 'B', 'BB', 'BBB', ...
const regExp = /[AB]+/g;

target.match(regExp); // -> ["A", "AA", "B", "BB", "A", "B"]
  • 범위를 지정하려면 [] 내에 -를 사용한다.
// 대문자 알파벳을 검색한다.

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

// 'A' ~ 'Z'가 한 번 이상 반복되는 문자열을 전역 검색한다.
// 'A', 'AA', 'AAA', ... 또는 'B', 'BB', 'BBB', ... 또는 'Z', 'ZZ', 'ZZZ', ...
const regExp = /[A-Z]+/g;

target.match(regExp); // ["A", "AA", "BB", "ZZ", "A", "B"]
  • 대소문자를 구별하지 않고 알파벳을 검색하는 방법은 다음과 같다.
const target = 'AA BB Aa Bb 12';

// 'A' ~ 'Z' 또는 'a' ~ 'z'가 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /[A-Za-z]+/g;

target.match(regExp); // -> ["AA", "BB", "Aa", "Bb"]
  • 숫자를 검색하는 방법은 다음과 같다.
const target = 'AA BB 12,345';

// '0' ~ '9'가 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /[0-9]+/g;

target.match(regExp); // -> ["12", "345"]
  • 위 예제를 간단히 표현하면 아래 예제와 같다.
  • \d는 숫자를 의미한다.
    • \d == [0-9]
  • \D는 \d와 반대로 동작하므로 숫자가 아닌 문자를 의미한다.
const target = 'AA BB 12,345';

// '0' ~ '9' 또는 ','한 번 이상 반복되는 문자열을 전역 검색한다.
let regExp = /[\d,]+/g;

target.match(regExp); // -> ["12,345"]

// '0' ~ '9'가 아닌 문자(숫자가 아닌 문자) 또는 ','가 한 번 이상 반복되는 문자열을 전역 검색한다.
regExp = /[\D,]+/g;

target.match*regExp); // -> ["AA BB ", ","]
  • \w는 알파벳, 숫자, 언더스코어를 의미한다.
    • \w는 [A-Za-z0-9_]와 같다.
  • \W는 \w와 반대로 동작하므로 알파벳, 숫자, 언더스코어가 아닌 문자를 의미한다.
const target = 'Aa Bb 12,345 _$%&';

// 알파벳, 숫자, 언더스코어, ','가 한 번 이상 반복되는 문자열을 전역 검색한다.
let regExp = /[\w,]+/g;

target.match(regExp); // -> ["Aa", "Bb', "12,345", "_"]

// 알파벳, 숫자, 언더스코어가 아닌 문자 또는 ','가 한 번 이상 반복되는 문자열을 전역 검색한다.
regExp = /[\W.]+/g;

target.match(regExp); // -> [" ", " ", ",'. " $%&"]

5.5 NOT 검색

  • [...] 내의 ^는 not의 의미를 갖는다.
    • [^0-9]는 숫자를 제외한 문자를 의미한다.
    • [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"]

5.6 시작 위치로 검색

  • [...] 밖의 ^은 문자열의 시작을 의미한다.
  • 단, [...] 내의 ^은 not의 의미를 가지므로 주의
const target = 'https://test.com';

// 'https'로 시작하는지 검사한다.
const regExp = /^https/;

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

5.7 마지막 위치로 검색

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

// 'com'으로 끝나는지 검색한다.
const regExp = /com$/;

regExp.test(target); // true
profile
전 척척학사지만 말하는 감자에요

0개의 댓글