정규표현식이 필요한 순간

회원가입 폼을 만든다고 가정해보자. 이메일, 전화번호, 비밀번호 입력값이 올바른지 검증해야 한다.

이걸 if문으로 처리하면 어떻게 될까.

if (pw.length >= 8) {
  if (hasUpper(pw)) {
    if (hasLower(pw)) {
      if (hasDigit(pw)) {
        if (hasSymbol(pw)) {
          // 여기까지 와야 통과다
        }
      }
    }
  }
}

조건이 복잡해질수록 if문이 끝없이 중첩된다. 비밀번호 하나만 해도 "영문 대소문자 포함, 숫자 포함, 특수문자 포함, 8자 이상"을 구현하려면 이미 막막하다.

정규표현식을 쓰면 같은 조건을 한 줄로 표현할 수 있다.

/^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$/.test(pw);

정규표현식이란

특정한 규칙을 가진 문자열의 집합을 표현하는 형식 언어다. 문자열의 검색과 치환에 특화된 도구다.

/^[\w.+-]+@[\w-]+\.[\w.-]+$/

처음 보면 외계어처럼 보인다.

하지만 쓰임새를 알면 이야기가 달라진다.

정규표현식이 필요한 상황

  • 각각 다른 포맷으로 저장된 전화번호 데이터를 추출해야 할 때
  • 사용자가 입력한 이메일, 휴대폰 번호, IP 주소가 올바른지 검증할 때
  • 코드에서 특정 변수 이름을 치환하되, 해당 변수를 포함한 함수는 제외하고 싶을 때
  • 특정 조건에 따라 문자열의 공백이나 특수문자를 제거할 때

요약하면 정규표현식은 검색치환 두 가지 카테고리로 나뉜다.


정규표현식 생성 방법

1) 리터럴 방식

var regex = /abc/;

문자열 양쪽을 슬래시(/)로 감싸는 방식이다. 패턴이 고정된 상수라면 성능에 유리하다.

2) 객체 생성자 방식

var regex = new RegExp("abc");

RegExp 생성자에 매개변수로 패턴을 선언한다. 패턴이 변경될 수 있거나, 사용자 입력에서 패턴을 가져와야 할 때 사용한다.


메소드

메소드형태반환값
test()regex.test(str)매칭되면 true, 아니면 false
exec()regex.exec(str)첫 매칭 정보 배열, 없으면 null
match()str.match(regex)매칭된 문자열 배열
replace()str.replace(regex, 대체값)치환된 새 문자열
search()str.search(regex)첫 매칭 위치, 없으면 -1
split()str.split(regex)패턴을 기준으로 나눈 배열

콘솔에서 직접 확인해보자.

const regex = /marketer/;
 
regex.test("i am a marketer");    // true
"i am a marketer".search(regex);  // 7
"i am a marketer".replace(regex, "growth hacker");
// "i am a growth hacker"

플래그 (고급 검색)

  • g (global): 전체 문자열에서 모든 매칭을 찾는다
  • i (case insensitive): 대소문자를 구분하지 않는다
  • m (multiline): 여러 줄에 걸쳐 검색한다
"Cat cat CAT".match(/cat/g);   // ["cat"]
"Cat cat CAT".match(/cat/gi);  // ["Cat", "cat", "CAT"]

패턴: 정규표현식의 핵심

1) Group and range

표현의미
(abc)괄호 안 전체를 하나의 그룹으로 묶는다
(?:abc)그룹으로 묶되 따로 캡처하지 않는다
a|ba 또는 b
[abc]a, b, c 중 하나
[a-z]a부터 z까지 중 하나
[^abc]a, b, c를 제외한 문자

2) Quantifiers

표현의미
a+a가 1회 이상
a*a가 0회 이상
a?a가 0회 또는 1회
a{3}a가 정확히 3회
a{2,}a가 2회 이상
a{2,4}a가 2회 이상 4회 이하
a+?게으른 수량자. 최소로 매칭하고 멈춘다

3) Boundary-type

표현의미
^문자열의 시작. m 플래그가 있으면 각 줄의 시작
$문자열의 끝. m 플래그가 있으면 각 줄의 끝
\b단어 경계
\B단어 경계가 아닌 위치

4) Character classes

표현의미
.줄바꿈을 제외한 모든 문자
\d숫자 0에서 9
\D숫자가 아닌 문자
\w영문자, 숫자, 언더스코어
\W\w에 해당하지 않는 문자
\s공백, 탭, 줄바꿈
\S공백이 아닌 문자

패턴 연습은 regexr.com에서 하는 것을 권장한다. 입력하면서 실시간으로 결과를 확인할 수 있다.


자주 쓰이는 패턴 모음

용도패턴
이메일/^[\w.+-]+@[\w-]+\.[\w.-]+$/
휴대폰 번호/^01[016789]-?\d{3,4}-?\d{4}$/
숫자만/^\d+$/
한글만/^[가-힣]+$/
날짜 YYYY-MM-DD/^\d{4}-\d{2}-\d{2}$/
URL/^https?:\/\/[^\s/$.?#].[^\s]*$/
모든 공백/\s/g
비밀번호 (영문, 숫자, 특수문자를 모두 포함한 8자 이상)/^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$/
2가지생성 방법 (리터럴 / 생성자)
3가지주요 플래그 (g / i / m)
4가지패턴 카테고리
검색+치환정규표현식의 핵심 기능

돌아보며

마케터가 정규표현식을 배우는 이유는 개발자가 되기 위해서가 아니다.
데이터를 직접 다룰 수 있어야 진단이 빠르고, 커뮤니케이션이 정확해진다.

처음에는 외계어처럼 보이지만, 자주 쓰이는 패턴 몇 가지만 익혀두면 실무에서 쓸 수 있는 순간이 생각보다 많이 온다.