[JS] 정규 표현식

김승현·2023년 2월 8일
0
  • 문자열에서 특정 문자 조합을 찾기 위한 패턴
  • 조건문 없이 패턴을 정의 하고 테스트 할 수 있다.

생성하는 2가지 방법

  1. 정규식을 리터털로 선언

    cosnt regex = /abc/;
    • 스크립트가 로드될 때 컴파일되므로, 정규식 문자열이 변하지 않는다면 리터럴 방식으로 선언하는 것이 성능상 조금 더 이점이 있다.
  2. 정규식 생성자 RegExp를 이용해서 생성

    cosnt regex = new RegExp("abc");
    • 정규식이 실행 시점에 컴파일되기 때문에 정규식을 동적으로 변화시켜야 할 때 유용

특수문자 이스케이프(Escape)

  • 몇몇 특수문자들은 특수한 용도로 사용되는 예억어이기 때문에 백슬래시(\)를 문자 앞에 붙여 문자 그대로 해석되도록한다.
const regex1 = /\*/;
const regex2 = /\?/;
const regex3 = /\./;
const regex4 = /\\/;

플래그(Flags)

  • 고급 검색을 위한 옵션 설정
  • 플래그는 리터럴 방식인지 생성자 방식인지에 따라 설정하는 방식이 다르다.
const regex1 = /패턴/flags;
const regex2 = new Regex(/패턴/, flags);
  • g (Global)
    • 패턴과 일치하는 모든 것을 검색. 해당 플래그가 없으면 일치하는 첫 번째 결과만 반환

      const str = 'banana';
      
      // g 플래그 없는 경우 : 최초에 발견되 문자만 반환
      str.match(/a/)  // [ 'a', index: 1, input: 'banana', groups: undefined ]
      // g 플래그 있는 경우 : 모든 결과 배열로 반환
      str.match(/a/g)  // [ 'a', 'a', 'a' ]
  • m (Multiline)
    • 문자열의 행이 바뀌더라도 계속 패턴 검색
  • i (Case Insensitive)
    • 대, 소문자 구별 없이 검색

      const str = 'banAna'
      str.match(/a/gi) // [ 'a', 'A', 'a' ]

메타 문자(Meta Charactor)

문자 그룹(Charactor Set, [] , [^])

  • 대괄호([])로 묶인 긍정 문자 그룹은 대괄호 내부의 문자열 중 하나라도 일치하는 경우를 의미
const str = 'gray and grey'

str.match(/gr[ae]y/g);   // [ 'gray', 'grey' ]

  • 대괄호 내부에 들어가는 특수문자는 메타 문자로 취급되지 않기 때문에 별도로 이스케이프 하지 않아도 된다.
const str = '!@#$%^&*.'

// [] 안에 있는 특수문자는 리터럴 특수문자 취급된다.
str.match(/[#.]/g);   // [ '#', '.' ]

  • 범위 지정 구문(dash, - )를 이용하여 간략하게 표기할 수 있다.
const regex1 = /[A-Z]/; // === /[ABCDEFGHIJKLMNOPQRSTUVWXYZ]/
const regex2 = /[0-9]/; // === /[0123456789]/
const regex3 = /[가-힣]/;

  • [^] 부정 문자 그룹(Negative Character Set)을 이용하여 대괄호에 해당하지 않는 문자열을 매칭할 수 있다.
const str = '2023 09 14 Monday';
// 숫자만 찾기
str.match(/[0-9]/g)  // ['2', '0', '2', '3', '0', '9', '1', '4']
// 숫자 제외하고 찾기
str.match(/[^0-9]/g) // [' ', ' ', ' ', 'M', 'o', 'n', 'd', 'a', 'y']

10진수 문자(Digit Character, \d, \D)

  • \d : [0-9] 와 동일
  • \D : [^0-9] 와 동일
const str = '2023 09 14 Monday';
// 숫자만 찾기
str.match(/\d/g)  // ['2', '0', '2', '3', '0', '9', '1', '4']
// 숫자 제외하고 찾기
str.match(/\D/g) // [' ', ' ', ' ', 'M', 'o', 'n', 'd', 'a', 'y']

단어 문자(Word Character , \w, \W)

  • \w : [0-9a-zA-z_] 와 동일(숫자, 영어 대소문자, 언더스코어(_)를 포함하는 그룹
  • \W : [^0-9a-zA-z_]
const str = '2023 09 14 Monday';
// 단어만 찾기
str.match(/\w/g)  // ['2', '0', '2', '3', '0', '9', '1', '4', 'M', 'o', 'n', 'd', 'a', 'y']
// 단어 아닌 것만 찾기
str.match(/\W/g)  // [' ', ' ', ' ']

공백 문자(Whitespace Character, \s, \S)

  • \s : 스페이스, 탭, 폼피드, 줄 바꿈 문자 등을 포함한 하나의 공백 검색
  • \S : \s의 역집합
const str = '2023 09 14 Monday';
// 공백만 찾기
str.match(/\s/g)  // [' ', ' ', ' ']
// 공백이 아닌것만 찾기
str.match(/\S/g)  // ['2', '0', '2', '3', '0', '9', '1', '4', 'M', 'o', 'n', 'd', 'a', 'y']

임의의 문자(Any Character, .)

. : 개행 문자를 제외한 모든 단일 문자에 해당

const str = '2023 09 14 Monday';

str.match(/./g)  
// ['2', '0', '2', '3', ' ', '0', '9', ' ', '1', '4', ' ', 'M', 'o', 'n', 'd', 'a', 'y']

str.match(/../g)
// ['20', '23', ' 0', '9 ', '14', ' M', 'on', 'da']

앵커(Anchor, ^, $ )

  • 메타 문자들은 어떤 문자열을 일치 시킬 것인지에 관한 것이였다면
  • 앵커는 입력된 정규식이 어떤 특정 위치에서 동작할지를 제한하는 역할의 문자
  • 즉, 위치만 제한할 뿐 검색 결과에는 포함되지 않는다.
  • ^ : 패턴 시작 앵커
    • 해당 정규식이 줄의 시작 부분인지 확인하는 역할
    • 문자 그룹([])에서의 부정 그룹을 나타내기 위한 캐럿(^)과는 다른 용법!
  • $ : 패턴 종료 앵커
    • 해당 정규식이 줄의 마지막 부분인지 확인하는 역할
const str1 = 'aaa';
const str2 = 'bab';

// str의 시작이 a 인지 검색
console.log(str1.match(/^a/))  // [ 'a', index: 0, input: 'aaa', groups: undefined ]
console.log(str2.match(/^a/))  // null
// str의 마지막이이 a 인지 검색
console.log(str1.match(/a$/))  // [ 'a', index: 2, input: 'aaa', groups: undefined ]
console.log(str2.match(/a$/))  // null

단어 경계(Word Boundaries, \b, \B)

  • \b : 다른 단어 문자(\w)가 앞이나 뒤에 등장하지 않는 위치임을 나타내는 문자
  • \B : \b 의 역집합
const str = " react and act";

// act 양옆에 단어 문자가 없는 것만 찾기
str.match(/\bact\b/); // [ 'act', index: 11, input: ' react and act', groups: undefined ]
// act 좌측에 단어 문자가 있는 것 찾기
str.match(/\Bact/);   // [ 'act', index: 3, input: ' react and act', groups: undefined ]

교체 구문(Alternation, |)

  • OR 연산자와 동일한 역할
  • 연산자 우선 순위가 가장 낮다.
const str = " react or act or enact";

str.match(/react|enact/g); // [ 'react', 'enact' ]

수량자(Quantifier)

  • 메타 문자들이 N회 반복됨을 나타내기 위한 문자
  • 적용하고자하는 문자 오른쪽에 붙인다.
  • 기본적으로 정규식은 탐용적이기 때문에, 수량자에 다양한 경우의 패턴이 매칭될 때에는 가능한 긴 패턴을 반환다.
const str = "abc";

// ab 또는 abc가 있는 찾기
// 반환 값으로 ab, abc 중 더 긴 abc 반환
str.match(/abc?/); // [ 'abc', index: 0, input: 'abc ab', groups: undefined ]
  • 반환 값으로 ab도 일치하고 abc도 일치하지만 정규식은 탐욕적이기 때문에 더 길고 많은 값을 반환한다.

게으른 수량자(Lazy Quantifier)

const str = "abc";

// ab 또는 abc가 있는 찾기
str.match(/abc??/); // [ 'ab', index: 0, input: 'abc', groups: undefined ]
  • 반환 값으로 ab도 일치하고 abc도 일치하지만 ?를 다시 붙여 게으르게 만듦으로서 가능한 더 적고 짧은 값을 반환

우선 범위 수량자 - 정확이 n 번 일치 ({n})

  • {m,n} : 최소 m번, 최대 n번 반복
const str = "xxx";

str.match(/x{1,3}/);   // [ 'xxx', index: 0, input: 'xxx', groups: undefined ]
str.match(/x{1,3}?/);  // [ 'x', index: 0, input: 'xxx', groups: undefined ]

  • {n} : 앞선 패턴이 n번 반복 === {n,n}
const str = "zxxzzxz";

str.match(/x{1}z/); // [ 'xz', index: 2, input: 'zxxzzxz', groups: undefined ]
str.match(/x{2}z/); // [ 'xxz', index: 1, input: 'zxxzzxz', groups: undefined ]

  • {n,} : 앞선 패턴이 최소 n번 이상 반복
const str = "zxxzzxz";

str.match(/x{1,}/)  // [ 'xx', index: 1, input: 'zxxzzxz', groups: undefined ]
str.match(/x{1,}?/) // [ 'x', index: 1, input: 'zxxzzxz', groups: undefined ]

  • + : 앞선 패턴이 한번 이상 반복 === {1,}
const str = "xxxx";

str.match(/xx+/)  // [ 'xxxx', index: 0, input: 'xxxx', groups: undefined ]
str.match(/xx+?/) // [ 'xx', index: 0, input: 'xxxx', groups: undefined ]

  • ? , ?? : 앞선 패턴이 1번 또는 0번 일치
const str = "xxxx";

str.match(/xx?/)  // [ 'xx', index: 0, input: 'xxxx', groups: undefined ]
str.match(/xx??/) // [ 'x', index: 0, input: 'xxxx', groups: undefined ]

  • * : 0번 이상 일치
const str = "xxxx";

str.match(/x*/)  // [ 'xxxx', index: 0, input: 'xxxx', groups: undefined ]
str.match(/x*?/) // [ '', index: 0, input: 'xxxx', groups: undefined ]


참조

정규표현식 완전정복 - 재그지그의 개발 블로그

[JavaScript] - 정규표현식

정규 표현식 - JavaScript | MDN

profile
개발자로 매일 한 걸음

0개의 댓글