본문 바로가기
03. 웹 표준 기술/JavaScript

12. 정규 표현식

by moca7 2024. 8. 19.

 

 

ㅁ < 정규 표현식 >

- Regular Expression이어서 regExp로 줄여서 얘기하곤 한다.

- 자바스크립트에서도 정규 표현식 객체를 제공한다.

생성자 함수가 있어서 그 생성자를 이용해서 생성시킬 수도 있다. 

- 자바스크립트뿐 아니라 자바, 오라클 등에서도 쓰인다.

- 줄여서 정규식이라고도 한다.

 

 

 
      < 정규표현식 >
 
      1. Regular Expression
      2. 어떤 문자열이 특정 패턴을 가지고 있는지 확인하기 위한 표현식.
      3. 정규표현식을 쓰게 되면 복잡한 조건검사를 할 필요가 없다. (길이 체크, 문자 하나씩 체크)
 
      4. JavaScript 정규식 작성 예시
         - 리터럴 표기법 외에 자바스크립트에서 제공하는 객체를 이용해서 생성도 가능하다.
 
         (1) 리터럴 표기법
             const reg = /pattern/[flags];        //  변수에 이런 패턴이 있는 정규 표현식을 담았다.
                                                                //  슬래시 뒤에 플래그 문자를 쓸 수도 있다. 생략도 가능.
 
         (2) 생성자 이용
             const reg = new RegExp('pattern'[, 'flags']);    // 인자값으로 패턴을 준다. 플래그 문자를 두번째 인자로 줄 수 있다.
             const reg = new RegExp(/pattern/[, 'flags']);    // 리터럴 표기법을 전달할 수도 있다. 문자열 형태가 아님.
 
 
      5. 정규식과 관련된 메소드
         1) 정규식.test(문자열)                      :   문자열 정규식과 일치하는 부분이 있으면 true / 없으면 false 반환
         2) 문자열.search(정규식)                 :   문자열 정규식과 일치하는 부분의 시작인덱스 반환 / 없으면 -1반환
         3) 문자열.replace(정규식, 바꿀값)   :   문자열에서 정규식과 일치하는 부분을 바꿀값으로 치환해서 반환
 

 

 

- test 메소드는 정규식 객체에서 제공하는 메소드다.

- 두번째, 세번째 메소드는 문자열 측에서 제공하는 메소드다.

 

- indexOf는 문자열만 가능하다면 search는 정규식 객체도 가능하다. 

- 문자열.replace는 정규식도 가능하다. 

 

 

 

 

ㅁ 정규식 패턴을 제시하는데 있어서 다양한 문자들이 활용된다.

- 대괄호 표기법, 메타문자, 이스케이프 문자 등등 종류가 굉장히 많다.

 

 
      < 정규식 메타 문자 (패턴 안에 쓰이는 문자들) >
 
 
      1) .
         ㄴ 모든 단일 문자를 의미 (무조건 한 문자)
         ㄴ ex) b.at : (o) baat, bbat, bcat, bdat, .. / (x) bat, baaat
 
      2) *
         ㄴ 0개 이상의 문자를 의미 (아예 없어도 됨) (참고로 *은 앞의 문자와 세트다. d라는 문자가 0개 이상이다.)
         ㄴ ex) good* : (o) goo, good, gooddd, .. 
 
      3) +
         ㄴ 1개 이상의 문자를 의미
         ㄴ ex) good+ : (o) good, goodd, gooddd, ... / (x) goo
 
      4) ?
         ㄴ 0개 또는 1개
         ㄴ ex) colou?r : (o) color, colour / (x) colouuur
 
      5) ^
         ㄴ 시작 문자를 의미
         ㄴ ex) ^a    : (o) app, apple, asia, .. / (x) banana, ...
 
      6) $
         ㄴ 종료 문자를 의미
         ㄴ ex) end$  : (o) end, the end, legend, .. / (x) ending, ...
 
      7) ()
         ㄴ 괄호내의 문자를 하나의 그룹으로 간주
         ㄴ ex) (app)+A : (o) appA, appappA, appappappA, .. / (x) appaA, ..
 
      8) |
         ㄴ 또는 을 의미
         ㄴ ex) a(b|c) : (o) ab, ac / (x) ad
 
      9) \
         ㄴ 이미 정규식에서 사용되고 있는 메타문자를 일반문자로 간주시키고자 할 때
         ㄴ ex) \*, \., \? , ...
 
     10) {m}
         ㄴ m개의 문자를 의미
         ㄴ ex) a{3}  : (o) aaa
 
     11) {m,}
         ㄴ m개 이상의 문자를 의미
         ㄴ ex) a{3,} : (o) aaa, aaaa, aaaaa, ...
 
     12) {m,n}
         ㄴ m개 이상 n개 이하의 문자를 의미
         ㄴ ex) a{1,3} : (o) a, aa, aaa
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[8.19월 9시~10시35분]

 

 

ㅁ 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>휴대전화 검사하기</h2>
    휴대전화 : <input type="text" id="mobile" placeholder="ex) 010-1234-5678">
    <button id="mobile-btn">확인</button>
    <div id="mobile-result"></div>


    <script>

        // 휴대전화 검사용 함수
        const verifyMobile = () => {
            // 010으로 시작하고 -와 함께 매번 4자리수로 두 세트 작성되어있는지 비교할 패턴 작성
            const regMobile = /^010(-[0-9]{4}){2}$/;      // () 그룹에 해당하는게 2 세트 오게끔
            const mobileInput = document.getElementById('mobile');
            const resultEl = document.getElementById('mobile-result');

            if( regMobile.test(mobileInput.value) ) {
                resultEl.innerHTML = '휴대전화 형식입니다.';
                resultEl.style.color = 'green';
            }
            else {
                resultEl.innerHTML = '휴대전화 형식에 맞지 않습니다.';
                resultEl.style.color = 'red';
                // mobileInput.focus();   //  텍스트 상자에 focus 효과(커서 깜빡) 주기
                mobileInput.select();     //  텍스트 상자에 select 효과(전체 구문 드래그 선택) 주기
                // 둘 다 사용자의 재입력 유도
            }
        }

        // 함수 바깥에 작성한다.
        document.getElementById('mobile-btn').addEventListener('click', verifyMobile);


    </script>


   
</body>
</html>
 

 

 

 

 

ㅁ 아이디 검사하기

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>아이디 검사하기</h2>
    아이디 : <input type="text" id="userId" placeholder="ex) user_01">
    <button id="userId-btn">확인</button>
    <div id="userId-result"></div>


    <script>

        // 아이디 검사용 함수
        const verifyUserId = () => {

            // 5~20자, 소문자/숫자/특수문자(-,_)로만, 첫글자는 소문자로 이루어져있는지 비교할 패턴
            const regUserId = /^[a-z][a-z0-9-_]{4,19}$/; // 앞에 첫글자가 있으니 19글자
            const userIdInput = document.getElementById('userId');
            const resultEl = document.getElementById('userId-result');

            // {4, 19} 정규표현식에 공백 있으면 의도대로 안 됨. {4,19}여야 의도대로 됨.

            if( regUserId.test(userIdInput.value) ) {
                resultEl.innerHTML = '아이디 형식입니다.';
                resultEl.style.color = 'green';
            }
            else {
                resultEl.innerHTML = '아이디 형식에 맞지 않습니다.';
                resultEl.style.color = 'red';
                userIdInput.select();
            }

        }
       
        document.getElementById('userId-btn').onclick = verifyUserId;


    </script>


   
</body>
</html>
 

 

 

 

 

ㅁ 비밀번호 검사하기

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>비밀번호 검사하기</h2>
    비밀번호 : <input type="text" id="userPwd" placeholder="ex) Password12!@">
    <button id="userPwd-btn">확인</button>
    <div id="userPwd-result"></div>


    <script>

        // 비밀번호 검사용 함수
        const verifyUserPwd = () => {

            // 5~20자, 대문자/소문자/숫자/특수문자(공백은 제외), 저 중에서 3가지 이상 사용해야함.
            //const regUserPwd = /^[a-zA-Z0-9!@#$%^&*()]{5,20}$/;   // 근데 이러면 3가지 이상 안써도 만족해버림.

            const userPwdInput = document.getElementById('userPwd');
            const resultEl = document.getElementById('userPwd-result');

            // 저 중에 몇 개를 쓰고 있는지 카운팅해야 함. 4개가 다 쓰였다면 4가 되어 있을 것이다.
            let passCount = /[a-z]/.test(userPwdInput.value); // 사용자가 입력한 값중에 저 패턴을 만족하는게 있는지. 있으면 true다. 자바스크립트에서는 true가 1이다. 처음엔 true가 담겼지만 덧셈연산이 되는 순간 1로 간주되었다.
            passCount += /[A-Z]/.test(userPwdInput.value);
            passCount += /[0-9]/.test(userPwdInput.value);
            passCount += /[^a-zA-Z0-9\s]/.test(userPwdInput.value)// 이건 시작을 제외하는 ^이 아니고 반대를 의미하는 ^다.
            // 공백은 \s

            console.log(passCount); // 현재 총 몇가지를 사용하고 있는지. passCount가 궁금하다면 이 구문 넣음.
           
           
            if( userPwdInput.value.length >= 5  &&  userPwdInput.value.length <= 20  &&  passCount >= 3 ) {
                resultEl.innerHTML = '비밀번호 형식입니다.';
                resultEl.style.color = 'green';
            }
            else {
                resultEl.innerHTML = '비밀번호 형식이 아닙니다.';
                resultEl.style.color = 'red';
                userPwdInput.select();
            }

            // 지금이야 text 타입이라 한글이 입력 가능하지만 password 타입이면 한글 입력 자체가 안된다.
            // 한글은 입력 안된다고 생각하시면 돼요.
        }
       
        document.getElementById('userPwd-btn').addEventListener('click', verifyUserPwd);


    </script>


   
</body>
</html>
 

 

 

 

 

 

 

ㅁ IP 주소 검사하기

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>IP 주소 검사하기</h2>
    IP 주소 : <input type="text" id="IP" placeholder="ex) 192.168.10.123">
    <button id="ip-btn">확인</button>
    <div id="ip-result"></div>


    <script>

        // ip 검사용 함수
        const verifyIp = () => {

            /*
                IP 형식 : 0.0.0.0 ~ 255.255.255.255
               
                (01안됨. 그냥 1임. 그게 ip형식이다. 012도 ip 형식 안맞다.)

                각 영역마다 한자리 / 두자리 / 세자리 일 수 있다.
                한자리 : 0 ~ 9 =>       [0-9]
                두자리 : 10 ~ 99 =>     [1-9][0-9]
                세자리 : 100 ~ 199 =>   1[0-9][0-9]     앞이 1로 시작한 경우 두자리 세자리에 0~9까지 올 수 있다.
                         200 ~ 249 =>   2[0-4][0-9]
                         250 ~ 255 =>   25[0-5]

                .을 기준으로 이 5가지중 하나가 온다.        
                ( [0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[0-4][0-9] | 25[0-5] )  
                 
                .이 3번 쓰인다. .은 메타문자다.
                ( [0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[0-4][0-9] | 25[0-5] )\.  =>  총 3세트
                ( [0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[0-4][0-9] | 25[0-5] )    =>  마지막

                [깃. 공백제거]
                ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.  => 총 3세트
                ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])    => 마지막에

            */

            const regIp = /^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/;
            const ipInput = document.getElementById('IP');
            const resultEl = document.getElementById('ip-result');

            if( regIp.test(ipInput.value) ) {
                resultEl.innerHTML = 'IP 형식입니다.';
                resultEl.style.color = 'green';
            }
            else {
                resultEl.innerHTML = 'IP 형식에 맞지 않습니다.';
                resultEl.style.color = 'red';
                ipInput.focus();
            }

        }


        document.getElementById('ip-btn').addEventListener('click', verifyIp);

    </script>


   
</body>
</html>
 

 

 

 

- 정규 표현식에 공백이 있으면 안 된다.

 

 

 

 

 

ㅁ 이메일 검사하기

- 이메일은 너무 다양해서 완벽한 정규식이 없다. 

.com 아니고 .co.kr도 있고, 한글로된 도메인도 있다.

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
    <h2>이메일 검사하기</h2>
    이메일 : <input type="text" id="email" placeholder="ex) user01@naver.com">
    <button id="email-btn">확인</button>
    <div id="email-result"></div>


    <script>

        // 이메일 검사용 함수
        const verifyEmail = () => {
            // 이메일형식 : 아이디@호스트.도메인 / 아이디@호스트.도메인.도메인
            //              (호스트 : 1글자 이상 / 도메인 : 2~6글자)

            const regEmail = /^[a-z][a-z0-9-_]{4,19}@[a-z0-9-]+(\.[a-z]{2,6}){1,2}$/;
            const emailInput = document.getElementById('email');
            const resultEl = document.getElementById('email-result');

            if( regEmail.test(emailInput.value) ) {
                resultEl.innerHTML = '이메일 형식입니다.';
                resultEl.style.color = 'green';
            }
            else {
                resultEl.innerHTML = '이메일 형식에 맞지 않습니다.';
                resultEl.style.color = 'red';
                emailInput.focus();
            }
        }

        document.getElementById('email-btn').addEventListener('click', verifyEmail);

    </script>



</body>
</html>
 

 

 

 

 

 

  • 현재 정규 표현식은 이메일 아이디가 소문자와 숫자, 하이픈(-), 언더스코어(_)만 포함할 수 있으며, 아이디는 5~20자 사이여야 합니다.
  • 호스트와 도메인은 소문자와 숫자, 하이픈(-)만을 허용합니다.
  • 도메인 부분의 길이는 2~6자이며, 도메인 부분이 두 개까지 허용됩니다.