4 minute read

Regular Expressions in JavaScript

Index

1. Introduction

  • 블로그에서 다루는 내용
    • 정규 표현식(Regular Expressions)이 무엇인가?
    • 정규 표현식이 왜 필요하며, 어디에 활용할 수 있는가?
    • 자세한 정규 표현식의 문법
    • 실제 샘플 코드를 통한 분석

1.1 정규 표현식(Regular Expressions) 란 ?

  • MDN 정규 표현식(Regular Expressions)은 다음과 같습니다.
  • 정규식은 문자열의 문자 조합을 일치시키는 데 사용되는 패턴입니다. JavaScript에서 정규 표현식도 객체입니다.

  • W3School 정규 표현식(Regular Expressions)
  • 정규식은 검색 패턴을 형성하는 일련의 문자입니다. 텍스트에서 데이터를 검색할 때 이 검색 패턴을 사용하여 검색하는 내용을 설명할 수 있습니다. 정규식은 단일 문자이거나 더 복잡한 패턴일 수 있습니다.

  • 위에서 보듯이 정규 표현식은 문자열중 원하는 패턴을 편하게 찾게하기 위한 방법 입니다.

1.2 왜 필요할까 ? 어디에 활용할 수 있을까 ?

  • 왜 필요할까 ?
    • 간단한 정규 표현식이 무엇인지 살펴봤지만, 아직도 애매합니다. 문자열(다수의 문자 집합)에서 원하는 문자를 찾는다 ? 왜 찾아야 할까요? 사례를 들어 보겠습니다.
      • 어느 개발자가 사용자 가입 정보중 나이를 입력받고 싶습니다. 보통 나이는 숫자(정수)로 입력 받고 싶죠.
      • 사용자가 입력하는 값이 문자는 아닌지 코드레벨에서 구분해야 합니다.(물론 개발 언어별 숫자,문자 구분 라이브러리가 존재 합니다. 이번 블로그에서는 제외 할께요.)
      • 이럴때, 정규 표현식을 사용하여 쉽게 입력 문자열에 대해서 숫자(정수) 여부를 구분할 수 있습니다.
  • 어디에 활용할 수 있을까 ?
    • 실제 사례를 몇가지 들어보게습니다. 이러한 사례를 해결하기 위해서 정규 표현식이 아닌 방식으로 코드 레벨에서 컨트롤 한다고 생각해 보세요.
      • 숫자만 입력받고 싶다.
      • 앞뒤로 공백이 하나씩 들어가야 한다.
      • 구체적인 스펙(영문자 혼용, 숫자만 허용, 6~8자리만 허용)이 있는 아이디만 입력 받고 싶다.
      • 올바른 메일 주소 형식인지 검사하고 싶다.
      • 휴대폰 번호 형식인지 검사하고 싶다.
      • 특수문자가 포함되어 있는지 알고 싶다.
    • 6가지 경우에 대해서만 생각해도 머리가 지끈지끈해 집니다. 이럴때 정규 표현식을 사용하면 간단하게 원하는 문자열에 패턴을 적용할 수 있습니다.

2. Body

2.1 정교 표현식 문법

  • /패턴/플래그
  • //사이에 찾을(매칭시킬) 패턴(아래의 패턴표나 MDN 참고) 작성
  • / 다음에 플래그을 위한 패턴(아래의 패턴이나 MDN 참고) 작성
  • 사용 예제
    • (/a-zA-Z/g)
      • /로 시작을 알림
      • a-z 찾을 패턴으로 소문자 영문 a에서 z까지
      • A-Z 찾을 패턴으로 대문자 영문 A에서 Z까지
      • /로 종료를 알림
      • / 다음에 전체에서 찾는다라는 옵션 g
      • ()로 한 그룹으로 묶음

2.1.1 매칭 패턴

패턴 설명
a-zA-Z 영문자, 소문자, 대문자
ㄱ-ㅎ가-힣 국문자
0-9 숫자
. 모든 문자(숫자, 한글, 영어, 특수기호, 공백, 공백제외
\d 숫자
\D 숫자가 아님
\w 영문, 숫자, 언더라인(_)
\W \w가 아님
\s 공백
\S 공백이 아님
\특수기호 특수기호

2.1.2 검색 패턴

패턴 설명
| 또는
[] 대괄호안의 문자들 중 한개
[^문자] 대괄호안의 문자를 제외
^문자열 문자열로 시작
문자열$ 문자열로 끝남
() 그룹, 그룹별로 묶음
(?:패턴) 그룹 검색
\b 단어의 처음/끝
\B 단어의 처음/끝 아님

2.1.3 수량 패턴

패턴 설명
? 최대한번(없거나, 한개이거나)
* 없거나 있거나(여러개 포함)
+ 최소한개(한개 또는 여러개)
{n} n개
{Min,} 최소 Min개 이상
{Min,Max] 최소 Min개 이상, 최대 Max개 이하

2.1.4 플래그(옵션)

옵션 설명
g Global 의미(매칭되는 첫번째만 검색)
i Ignore Case 의미(대소문자 구분안함)
m Multi line 의미(여러행의 문자열 검색

2.1.5 주요 함수

함수 설명
(“문자열”).match(/정규표현식/플래그) “문자열”에서 match내의 패턴이 매칭되는 항목을 배열로 반환
(“문자열”).replace(/정규표현식/, “대체문자열”) /정규표현식/에 매칭되는 항목을 "대체문자열"로 변환
(“문자열”).split(정규표현식) "문자열"정규표현식에 매칭되는 항목으로 분리하여 배열로 반환
(정규표현식).test(“문자열”) "문자열"정규표현식과 매칭되면 ture, 아니면 false 반환
(정규표현식).exec(“문자열”) match와 동일하나, 첫번째 매칭 결과만 반환

2.2 실제 샘플 코드를 통한 분석

2.2.1 메일 주소 형식에 대해서 정규 표현식을 통한 코드 샘플을 살펴 보겠습니다

<input type="email" name="" id="email" value="" />
<button onclick="doSave();">저장</button>

<script>
const regexpEmail = /^([a-z]+\d*)+(\.?[a-z]+\d*)+@([a-z]+\d*)+(\.[a-z]{2,3})+$/;

function doSave() {
  const email = document.getElementById("email").value;
  console.log(email);
  if (!regexpEmail.test(email)) {
    alert("이메일 형식이 맞지 않습니다. 올바른 형식으로 입력하세요.");
  }
}
</script>
  • /^([a-z]+\d)+(\.?[a-z]+\d)+@([a-z]+\d*)+(\.[a-z]{2,3})+$/
    • //로 시작과 끝을 의미

  • /^([a-z]+\d)+(\.?[a-z]+\d)+@([a-z]+\d*)+(\.[a-z]{2,3})+$/
    • ^ 이후의 문자열로 시작하고, $ 이전 문자열로 끝남

  • /^([a-z]+\d*)+(\.?[a-z]+\d)+@([a-z]+\d)+(\.[a-z]{2,3})+$/
    • ([a-z]+\d*)+
      • ()로 그룹으로 묶고, +()묶음이 최소한개 이상

    • ([a-z]+\d*)+
      • []로 내부의 패턴중 한개, a-z 영문 소문자 a에서 z까지를 +로 최소한개 이상

    • ([a-z]+\d*)+
      • \d 숫자

    • ([a-z]+\d*)+
      • * 여러개 포함

  • /^([a-z]+\d)+(\.?[a-z]+\d*)+@([a-z]+\d)+(\.[a-z]{2,3})+$/
    • (\.?[a-z]+\d*)+
      • \.로 .을 일반문자로 인식

    • (\.?[a-z]+\d*)+
      • ? 최대 한번

    • (\.?[a-z]+\d*)+
      • 소문자 a에서 z까지 최소 한개 이상

    • (\.?[a-z]+\d*)+
      • 숫자 여러개 포함

  • /^([a-z]+\d)+(\.?[a-z]+\d)+@([a-z]+\d*)+(\.[a-z]{2,3})+$/
    • @([a-z]+\d*)+
      • @ 일반문자

    • @([a-z]+\d*)+
      • 소문자 a에서 z까지 최소한 한개 이상, 숫자 여려개 포함한 묶음이 최소 한개 이상

  • /^([a-z]+\d)+(\.?[a-z]+\d)+@([a-z]+\d*)+(\.[a-z]{2,3})+$/
    • (\.[a-z]{2,3})+
      • \.로 .을 일반문자로 인식

    • (\.[a-z]{2,3})+
      • 소문자 a에서 z까지 최소한 한개 이상, 최소 2개 이상 최대 3개 이하

    • (\.[a-z]{2,3})+
      • 한 묶음으로 최소 한번 이상

2.2.2 문제

  • 문제.사용자가 입력한 아이디를 파라미터로 받고, 사용자 아이디가 다음 조건을 만족하는지 확인하는 함수를 작성하세요.
    • 사용자 아이디는 5자리 이상 15자리 이하입니다.
    • 알파벳 소문자, 숫자, 밑줄(_), 마침표(.)만 포함할 수 있습니다.
    • 밑줄은 연속해서 2개 사용할 수 없습니다.
    • 마침표는 1개만 사용할 수 있습니다.
    • 아이디 시작은 반드시 소문자여야 합니다.
    • 아이디 마지막 문자는 소문자 또는 숫자만 가능합니다.
    • 조건을 만족하면 true, 만족하지 않으면 false 반환하세요.
<body>
    <input type="text" name="" id="id" value="" placeholder="아이디를 입력하세요." />
    <button onclick="checkId();">체크</button>
    <br /><br />
    <textarea id="txt"></textarea>
    <script>
        function checkUserId(userId) {
            //1. 사용자 아이디는 5자리 이상 15자리 이하입니다.
            if (!/^.{5,15}$/.test(userId)) {
                document.getElementById("txt").value = "사용자 아이디는 5자리 이상 15자리 이하입니다.";
                return false;
            }

            //2. 알파벳 소문자, 숫자, 밑줄(_), 마침표(.)만 포함할 수 있습니다.
            if (!/[a-z0-9_\.]+/.test(userId)) {
                document.getElementById("txt").value = "알파벳 소문자, 숫자, 밑줄(_), 마침표(.)만 포함할 수 있습니다.";
                return false;
            }

            //3. 밑줄은 연속해서 2개 사용할 수 없습니다.
            if (/_{2}/.test(userId)) {
                document.getElementById("txt").value = "밑줄은 연속해서 2개 사용할 수 없습니다.";
                return false;
            }

            //4. 마침표는 1개만 사용할 수 있습니다.
            if (userId.split(/\./).length > 2) {
                document.getElementById("txt").value = "마침표는 1개만 사용할 수 있습니다.";
                return false;
            }

            //5. 아이디 시작은 반드시 소문자여야 합니다.
            if (!/^[a-z]/.test(userId)) {
                document.getElementById("txt").value = "아이디 시작은 반드시 소문자여야 합니다.";
                return false;
            }

            //6. 아이디 마지막 문자는 소문자 또는 숫자만 가능합니다.
            if (!/[a-z0-9]$/.test(userId)) {
                document.getElementById("txt").value = "아이디 마지막 문자는 소문자 또는 숫자만 가능합니다.";
                return false;
            }

            return true;
        }

        function checkId() {
            const userId = document.getElementById("id").value;
            if (checkUserId(userId)) {
                document.getElementById("txt").value = "정상적인 아이디 입니다.";
            }
        }
    </script>
</body>

3. Conclusion

  • 서두에 언급한 6가지 사례에 대해서 모두 다루지는 않았지만, 이메일 주소형식을 제대롤 이해 한다면, 5가지 사례는 충분히 가능하리라 생각 합니다.
  • 정규식 표현을 위해서는 별도의 추가 문법에 대해서 알아야만 가능하며, 정규식 표현이 코드레벨에서 얼마나 많이(자주) 사용될지 짐작이 가능 합니다.

4. Reference

Leave a comment