티스토리 뷰

정규 표현식 🤔

정규 표현식(Regular Expression)은 특정한 패턴을 가진 문자열의 집합을 표현하기 위한 문법입니다. 자바스크립트 외에도 많은 프로그래밍 언어들이 지원하고 있으며, 정규 표현식을 활용하여 문자열 내에서 발견한 패턴을 자유롭게 추출하거나 변환할 수 있습니다. 이를 패턴 매칭(Pattern Matching)이라 말합니다.

 

패턴 매칭 기능을 통해 입력 받은 문자열 내에서 전화번호나 이메일 주소를 찾을 수도 있고, HTML 문서 내에서 찾고자 하는 태그 내의 데이터를 추출하거나 변경할 수도 있습니다. 비록 정규 표현식이 알아보는 것에 있어 실제 문자열과 차이가 있기 때문에 이해하기 어려울 수 있지만, 초반 개념을 잘 이해하면 간편하게 사용할 수 있습니다.

 

regexr.com 사이트에서 정규 표현식을 연습할 수 있습니다.

 

정규 표현식 생성 ⚡️

정규 표현식 객체(RegExp)를  만드는 방법에는 생성자와 리터럴을 이용한 방식이 있습니다.

 

// RegExp(표현식, 플래그)
const regexp1 = new RegExp('^abc');
const regexp2 = new RegExp('^abc', 'gi');

// 리터럴 /표현식/플래그
const regexp3 = /^abc/;
const regexp4 = /^abc/gi;

 

표현식은 입력된 문자열 내에서 찾고자 하는 패턴이라 생각하면 되고, 플래그는 매칭되는 패턴을 찾을 때 추가로 설정하는 옵션이라 보면 됩니다. 이처럼 정규 표현식 객체는 표현식과 플래그로 구성되는데, 플래그는 설정할 필요가 없다면 필수로 작성하지 않아도 됩니다.

 

정규 표현식에서 사용하는 플래그는 6가지가 있지만, 3가지 정도를 비교적 많이 사용합니다.

  •  i : 대소문자를 구분하지 않고, 패턴과 일치하는 문자열을 추출합니다. (ignore case)
  • g : 매칭 중인 문자열 내에서 패턴과 일치하는 모든 문자열을 추출합니다. (global)
  • m : 문자열의 행이 넘어가더라도 검색을 계속합니다. (multi line)

 

정규 표현식 메소드 🔥

정규 표현식을 사용하는 메소드는 RegExp 객체 외에도 String 객체에서 사용할 수 있습니다.

 

const target = 'hello world, Hello NoHack!';
const regexp = /hello/;

// RegExp 객체의 exec 메소드 (매칭 결과를 배열로 반환)
// ['hello', index: 0, input: 'hello world, Hello NoHack!', groups: undefined]
console.log(regexp.exec(target));

// RegExp 객체의 test 메소드 (매칭 결과를 T/F로 반환)
// true
console.log(regexp.test(target));

// String 객체의 match 메소드 (매칭 결과를 배열로 반환)
// ['hello', index: 0, input: 'hello world, Hello NoHack!', groups: undefined]
console.log(target.match(regexp));

 

exec와 match 메소드는 문자열 내에 표현식과 일치하는 부분이 있으면 매칭 정보를 배열로 반환하고, 일치하는 부분이 없다면 null을 반환합니다. 하지만 두 메소드는 한 가지 차이점이 있으니 사용 시 유의해야 합니다. g 플래그를 적용해서 전역으로 검색을 할 때, exec 메소드는 첫 번째로 일치하는 부분에 대한 정보만을 출력하지만, match 메소드는 일치하는 모든 문자열을 배열로 출력합니다.

 

String 객체의 search, replace, split 메소드도 알아 보겠습니다.

 

const target = 'hello world, Hello NoHack!';
const regexp = /Hello/;

// 매칭되는 첫 문자열의 인덱스를 반환합니다.
// 13
console.log(target.search(regexp));

// 매칭되는 부분의 문자열을 교체 후 반환합니다.
// Hi wolrd, Hello NoHack!
console.log(target.replace(/hello/, 'Hi'));

// 매칭되는 문자열을 분할하여 배열로 반환합니다.
// ['hello world', 'Hello NoHack!']
console.log(target.split(/, /));

 

replace 메소드에 사용되는 표현식을 전역으로 적용하면, 매칭되는 모든 문자열을 교체합니다. 그리고 정규 표현식에서 사용되는 메소드는 모두 결과를 반환만 하고, 원본 데이터는 변경하지 않기 때문에 부수 효과(Side Effect)가 발생하지 않는 것을 확인할 수 있습니다.

 

정규 표현식 패턴 🌈

정규 표현식에서 사용할 수 있는 패턴은 문자 외에도 특별한 의미를 가지는 메타 문자를 사용할 수 있습니다. 자바스크립트에서 사용할 수 있는 메타 문자는 정말 많기 때문에, 본문에서는 자주 사용되는 문자 위주로 소개하겠습니다. 메타 문자는 의미와 직관되지 않는 부분이 많기 때문에 계속 해보면서 외우는 것도 중요하다 생각됩니다.

 

1. 임의의 문자 검색

 

const target = 'hello world, Hello NoHack!';

// ['hel', 'lo ', 'wor', 'ld,', ' He', 'llo', ' No', 'Hac']
console.log(target.match(/.../g));

 

.은 임의의 문자 하나를 의미하는 기호이며, 사용하는 개수만큼 문자의 종류와 관계 없이 대응됩니다.

 

2. 반복 검색

 

const target = 'A AA AAA B BB BBB Aa Bb ABA';

// A가 2번 반복되는 문자열을 의미합니다.
// ['AA', 'AA']
console.log(target.match(/A{2}/g));

// A가 2번 이상 반복되는 문자열을 의미합니다.
// ['AA', 'AAA']
console.log(target.match(/A{2,}/g));

// A가 1번 이상, 2번 이하 반복되는 문자열을 의미합니다.
// ['A', 'AA', 'AA', 'A', 'A',  'A', 'A']
console.log(target.match(/A{1,2}/g));

 

반복 검색은 중괄호 앞에 적혀 있는 표현식을 중괄호 안에 적힌 숫자에 따라 검색하는 방법입니다. 괄호 내부를 어떻게 작성했는지에 따라 동작이 약간 달라지니 잘 확인하고 넘어가야 합니다.

 

3. OR 검색

 

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

// ['A', 'AA', 'B', 'BB', 'A', 'B']
console.log(target.match(/A+|B+/g));

// ['A', 'AA', 'B', 'BB', 'A', 'B']
console.log(target.match(/[AB]+/g));

 

OR 연산을 의미하는 기호인 |은 정규 표현식에서도 동일하게 동작합니다. OR은 간편하게 [] 대괄호로 표현할 수도 있으며, 대괄호 안에 적힌 내용은 모두 기본적으로 OR 연산이 적용됩니다. 그리고 + 기호는 메타 문자 중 하나로, 앞에 적힌 표현식이 최소 1회 이상 반복되는 것을 의미합니다.

 

+와 더불어 아래 기호를 추가로 알아두면 좋습니다.

  • * : 0회 이상 반복 ({0, }과 동일)
  • + : 1회 이상 반복 ({1, }과 동일)
  • ? : 0 또는 1회 반복
  • ^ : 다음에 적힌 표현식으로 시작을 의미 (^abc)
  • $ : 이전에 적힌 표현식으로 끝남을 의미 (abc$)
  • [^abc] : a | b | c의 부정을 의미

 

대괄호 안에서는 검색하고자 하는 범위도 지정해줄 수 있습니다.

 

const target = '12,345';

// ['12', '345']
console.log(target.match(/[0-9]+/g));

// ['12,345']
console.log(target.match(/[0-9,]+/g));

 

쉼표까지 포함해서 검색하고 싶다면, 위 코드처럼 [0-9,]+ 패턴을 적용하면 됩니다. 그리고 범위 지정은 숫자뿐 아니라 문자에도 동일하게 적용(a-z, A-Z)할 수 있습니다.

 

마지막으로 특별한 기호 몇 가지만 소개하고 마무리 하겠습니다.

  • \w : 63개의 문자(영어 대소문자, 숫자 10개, _)
  • \W : 63개 문자를 제외한 나머지
  • \d : 숫자
  • \D : 숫자가 아닌 문자
  • \s : 공백(space, tab 등)
  • \S : 공백을 제외한 나머지
  • \b : 63개의 문자(영어 대소문자, 숫자 10개, _)가 아닌 나머지 문자에 일치하는 경계(boundary)
  • \B : 63개 문자에 일치하는 경계(boundary)

 

여기까지 이해하게 되면 입력된 문자열이 전화번호인지 판별할 수 있습니다.

 

const phone = '010-1234-5678';

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

 

참고 📖

정규 표현식, 이렇게 시작하자!

 

 

'Tech Stack > 자바스크립트' 카테고리의 다른 글

이터레이션 프로토콜  (0) 2021.05.14
새로운 원시 타입 Symbol  (0) 2021.05.14
배열을 다룰 때 내가 주로 사용하는 방법  (0) 2021.05.14
this 바인딩  (0) 2021.05.12
strict mode  (0) 2021.05.12
댓글