본문 바로가기
카테고리 없음

자바스크립트 정규표현식 (Regular expression)

by ttum 2021. 5. 28.

매번 정규 표현식을 사용할 때마다 제대로 이해하지 못한 코드를 가져다 사용하는 것이 싫어 공부해보기로했다. 이번에는 적어도 핸드폰번호와 이메일 정규 표현식은 내가 직접 만들어야겠다.

정규 표현식 만들기

자바스크립트에서 정규 표현식을 만드는 방법은 두 가지가 있다.

  1. 정규식 리터럴을 사용하기const regex = /ab+c/;
  2. RegExp 객체의 생성자 함수를 호출하기const regex = new RegExp("ab+c");

정규식 리터럴을 사용하면 스크립트를 불러올 때 컴파일이 된다. 만약 정규식이 상수라면 리터럴 방식을 사용하는 것이 좋다.

반면 생성자 함수를 호출하는 방식은 런타임시에 컴파일이 된다. 그래서 정규식의 패턴이 동적으로 변해야하는 경우에 생성자함수를 사용하면 된다.

사용자에게서 정규 표현식 패턴을 직접 입력하는 것이 흔한 일은 아니므로 나는 리터럴 방식으로 사용하겠다.

 

정규 표현식 문자의 종류

정규표현식의 각 문자는 아래의 두 개로 나뉜다.

  • 정규 문자 (말 그대로 리터럴 문자)
  • 메타 문자(특정 패턴을 기술하는 문자)

예를 들어 /ab/ 라는 정규 표현식이 있다면, 말 그래로 문자열 중에서 문자열 'ab'가 포함된 것을 찾을 것이다. 가령 'banana' 같이 말이다.

그러나 정규 표현식을 사용하는 주된 목적은 저렇게 단순한 문자열을 찾기 위함이 아니다. 조금 더 복잡하고 다양한 케이스의 경우를 다루게 되는데, 이때 사용되는 것이 메타 문자다.

/a*b/ 라는 정규 표현식이 있다면, 'a*'와 'b' 이렇게 나누어 생각할 수 있다. 메타 문자인 ''는 0번 이상 발생하는 경우에 매칭된다. 따라서 'aaab', 'aaaaaaab', 'b' 등이 매칭될 수 있다. 메타문자는 '' 말고도 굉장히 다양한 것이 있는데 모든 메타 문자를 외우고있을 수는 없다. 따라서 필요할때 찾아서 사용하면 될 듯하고, 중요한 것은 정규 표현식을 보고 메타 문자에 따라 잘 나눌 수 있는가이다.

 

POSIX 기본 및 확장 표준 문법

메타 문자 기능 설명
. 문자 1개의 문자와 일치한다. 조커 같은 느낌으로 사용할 수 있다. 가령 /gr.y/ 면 'gr'과 'y' 사이에 아무 문자나 1개가 포함되면 매칭된다.
[ ] 문자 클래스 또는(or)을 표시하는 문자열은 | 이다. 이를 여러 개 사용한 것과 같은 의미다. 가령 /[abc]//a|b|c/ 와 같다. '-' 기호와 함께 사용하면 범위를 표현할 수도 있다. '[a-z]'는 소문자 문자열 하나를, '[A-Z]'는 대문자 문자열 하나를, '[0-9]'는 0부터 9 사이의 숫자 하나를 의미한다.
[^ ] 부정 문자열 클래스 안의 문자를 제외한 나머지를 선택한다.
^ 처음 문자열이나 행의 처음을 의미한다.
$ 문자열이나 행의 끝을 의미한다.
( ) 하위식 여러 식을 하나로 묶을 수 있다. 사칙연산에서의 괄호와 비슷한 역할이다. /abc|adc//a(b|d)c/ 와 같은 의미다.
\n 일치하는 n번째 패턴 일치하는 패턴들 중 n번째를 선택하며, 여기서 n은 1에서 9 중 하나가 올 수 있다.
* 0회 이상 0개 이상의 문자를 포함한다. /a*b/는 'b', 'ab', 'aab', 'aaab' 등과 매칭된다.
{m,n} m회 이상 n회 이하 /a{1,3}b/ 는 a가 1회에서 3회까지 반복되는 경우 매칭한다.

 

예제

이메일 정규 표현식

function isValidEmail(email) { const emailRegExp = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[0-9a-zA-Z]{2,5}$/gi; return email.match(emailRegExp); }

/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[0-9a-zA-Z]{2,5}$/gi

  • ^: 문자열이나 행의 시작을 의미
  • [0-9a-zA-Z]: 처음에는 숫자 또는 영문자 한 개가 있어야 한다.
  • [-_.]?: 메타문자 '?'는 0 또는 1회 등장하는 경우를 의미한다. 따라서 '-', '_', '.'중 하나가 등장해도 되고 아니어도 된다는 의미다.
  • [0-9a-zA-Z]: 숫자 또는 영문자가 나와야 한다는 의미다.
  • ⇒([-_.]?[0-9a-zA-Z])* : 앞에서 말한 특수 문자나 영문자, 숫자의 조합이 0회 이상 반복된다는 의미다.
  • @ : 말 그대로 골뱅이 문자열이 포함되어야 한다는 의미.
  • [0-9a-zA-Z] : 메일 주소 역시 영문자 또는 숫자로 시작해야 한다.
  • ([-_.]?[0-9a-zA-Z])*: 마찬가지로 그 후에는 특수 문자나 영문자 숫자 등이 등장할 수 있다.
  • . : 메일주소는 닷(.)이 포함되어야 하므로 추가해준다.
  • [0-9a-zA-Z]{2,5}: 닷 다음에는 com이나 net, io 등 여러가지로 마무리될 수 있다. 여기에는 특수문자는 포함되면 안되고 영문자와 숫자만 넣을 수 있도록 했다. 원한다면 숫자는 제외해도 좋다. 영문자와 숫자가 최소 2자리부터 최대 5자리까지 오면 인정을 해주겠다는 의미. 상황에 따라 이 길이도 조정해도 되며, 항상 '.com'으로 끝나야한다면 리터럴로 'com'이라고 그대로 적어주면 된다.
  • $ : 문자열이나 행의 마지막을 의미
  • g : 매칭되는 값이 하나 리턴된 후에 종료함.
  • i : 대소문자 구분하지 않음.

전화번호(핸드폰 번호) 유효성 검사

function isValidMobileNumber(mobileNumber) { constmobileNumberRegExp = /^[0-9+]*([0-9]{2,4}[-])+([0-9]{2,4})$/g; returnmobileNumber.match(mobileNumberRegExp); }

/^([0-9]{2,4}[-])+([0-9]{2,4})$/g

목표는 02-1234-5678 또는 010-0000-0000 등의 전화번호를 만드는 것이다. 숫자와 기호(-)가 여러번 반복된 후에 마지막에 숫자 2개에서 4개가 반복되며 마무리 되는 것을 목표로 함.

  • ^: 문자열이나 행의 시작을 의미
  • ([0-9]{2,4}[-])+: 0부터 9 사이의 숫자가 2부터 4개까지 반복된 후에 '-' 기호가 등장하는 일이 1번 이상 등장함.
  • ([0-9]{2,4}): 마지막에는 숫자가 2개에서 4개 사이로 마무리가 됨.
  • $: 문자열이나 행의 마지막을 의미.
  • g: 매칭되는 값이 하나 리턴된 후에 종료함.

Reference