본문 바로가기

TIL/JavaScript

[JavaScript] 정규표현식

정규 표현식

- 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식 언어로 정규 표현식을 이용하면 입력 된 문자열에 대하여 특정 조건 검색, 치환 가능
- 복잡한 조건문 대신 간단하게 처리 가능

 

정규 표현식(Regular Expressions)의 객체 생성

- 자바스크립트에서는 RegExp 객체와 문자열 메소드를 조합해 정규 표현식을 사용한다.
- 정규 표현식은 패턴(pattern)과 선택적으로 사용할 수 있는 플래그(flag)로 구성된다.

    <script>
        // 정규식 생성 문법 1
        // 상황에 따라 동적으로 생성 된 문자열을 정규식으로 만들어야 하는 경우
        let regExp = new RegExp('pattern', 'gmi');
        // 정규식 생성 문법 2
        // 코드 작성 시 이미 패턴을 알고 있을 경우 
        regExp = /pattern/;
        regExp = /pattern/gmi;
    </script>

 

정규식 사용 메소드

정규 표현식 메소드
- test : 문자열에서 정규식 변수의 값과 일치하는 값이 있으면 true, 없으면 false 반환

 

문자열 메소드
- match : 문자열에서 정규식 변수의 값과 일치하는 모든 값 반환
- replace : 문자열에서 정규식 변수이 값과 일치하는 부분을 새로운 값을 변경
- search : 일치하는 부분의 시작 인덱스 반환
- split : 정규식 변수에 지정 된 값을 구분자로 하여 배열 생성

 

    <button id="test1">확인하기</button>
    <div id="area1" class="area"></div>
    <script>
        document.querySelector("#test1").addEventListener('click', function(){
            // 검색 대상 문자열
            let str = 'javascript jquery ajax';

            // 정규식 변수(검색 조건으로 삼을 문자열)
            let regExp = /script/;

            // area에 표현할 html
            let html = '';

            html += "str : " + str + "<br>";
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "match : " + str.match(regExp) + "<br>";
            html += "replace : " + str.replace(regExp, '스크립트') + "<br>";
            html += "search : " + str.search(regExp) + "<br>";
            html += "split : " + str.split(regExp) + "<br>";


            document.querySelector("#area1").innerHTML = html;
        });
    </script>

 

메타 문자를 이용한 문자 검색, 치환

^ : 텍스트의 시작
ex. /^a/ : 소문자 a로 시작하는 패턴


[] : 범위 표현
ex. /[ab]/ : 소문자 a 또는 b, /[a-z]/ : 소문자, /[A-Z]/ : 대문자, /[A-Za-z]/ : 대소문자, /[0-9]/ : 숫자


$ : 텍스트의 끝
ex. /z$/ : 소문자 z로 끝나는 패턴


. : 어떤 문자가 오던 매칭
ex. /a.c/ : a와 c 사이에 아무 문자 하나가 있는 패턴


+ : 앞의 문자를 1개 이상 찾음
ex. /a+/ : a 또는 aa 또는 aaa ...

    <button id="test2">실행확인</button>
    <div id="area2" class="area"></div>
    <script>
        document.querySelector("#test2").addEventListener('click', function(){
            let str = 'javascript jquery ajax';
            let regExp = /a/;
            let html = '';

            html += "str : " + str + "<br>";
            html += "regExp : " + regExp + "<br>";

            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";

            // ^ : 텍스트의 시작을 의미
            regExp = /^j/;
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";

            // [] : [] 내의 문자 중 하나라도 존재할 경우
            regExp = /[ab]/;
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";

            // j 또는 s로 시작
            regExp = /^[js]/;
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";

            // $ : 텍스트의 끝을 의미
            regExp = /x$/;
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";

            // . : 개행 문자를 제외한 모든 문자
            // + : 한 글자 이상
            // j로 시작해서 x로 끝나는 패턴 (중간에 최소 1개 이상의 문자는 있음)
            regExp = /^j.+x$/;
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";

            // 숫자만(시작^ 부터 1글자 이상+ 끝$ 까지 [0-9]일때)
            regExp = /^[0-9]+$/;
            str = "1234567890";
            html += "str : " + str + "<br>";
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";

            // 영어 대문소문자 + 숫자만
            regExp = /^[a-zA-Z0-9]+$/;
            str = "JavaScript123";
            html += "str : " + str + "<br>";
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";

            // 한글만
            regExp = /^[ㄱ-ㅎㅏ-ㅣ가-힣]+$/;
            str = "ㅎㅇ";
            html += "str : " + str + "<br>";
            html += "regExp : " + regExp + "<br>";
            html += "test : " + regExp.test(str) + "<br>";
            html += "replace : " + str.replace(regExp, '(***)') + "<br>";


            document.querySelector("#area2").innerHTML = html;
        });
    </script>

 

플래그 문자

g : 전역 비교를 수행
i : 대소문자를 가리지 않고 비교
m : 여러 줄의 검사 수행

    <button id="test3">실행확인</button>
    <div id="area3" class="area"></div>
    <script>
        document.querySelector("#test3").addEventListener('click', function(){
            let str = 'JavaScript JQuery Ajax';
            let regExp = /a/;
            let html = '';

            html += "str : " + str + "<br>";
            html += "regExp : " + regExp + "<br>";
            html += "replace : " + str.replace(regExp, "($&)") + "<br>";
            // $& : 대체 문자열에 일치하는 전체 문자열의 복사본을 포함

            regExp = /a/g;
            html += "regExp : " + regExp + "<br>";
            html += "replace : " + str.replace(regExp, "($&)") + "<br>";

            regExp = /a/gi;
            html += "regExp : " + regExp + "<br>";
            html += "replace : " + str.replace(regExp, "($&)") + "<br>";

            str = "JavaScript\nJQuery\nAjax";
            regExp = /^j/gi;
            html += "regExp : " + regExp + "<br>";
            html += "replace : " + str.replace(regExp, "($&)") + "<br>";

            regExp = /^j/gim;
            html += "regExp : " + regExp + "<br>";
            html += "replace : " + str.replace(regExp, "($&)") + "<br>";

            regExp = /[^j]/gim;
            // 대괄호 안에서 ^는 부정
            html += "regExp : " + regExp + "<br>";
            html += "replace : " + str.replace(regExp, "($&)") + "<br>";

            document.querySelector("#area3").innerHTML = html;
        });
    </script>

 

추가 메타 문자

\d : digit(숫자)
\w : word(알파벳 + 숫자 + _)
\s : space(공백문자 - 탭, 띄어쓰기, 줄바꿈)
\D : non digit(숫자가 아닌 문자)
\W : non word(알파벳 + 숫자 + _가 아닌 문자)
\S : non space(공백 문자가 아닌 문자)

    <label>주민등록번호 입력 : </label>
    <input type="text" id="pno">
    <button id="test4">실행확인</button>
    <script>
        document.querySelector("#test4").addEventListener('click', function(){
            // 입력 값
            let pno = document.querySelector("#pno").value;
            // 자리수 맞춤
            let regExp = /^......-.......$/;
            // 자리수 + 숫자만 가능
            regExp = /^\d\d\d\d\d\d-[1234]\d\d\d\d\d\d$/;

            if(regExp.test(pno)) {
                alert('정상 입력!');
            } else {
                alert('잘못 된 입력!');
            }
        });
    </script>

 

수량 문자

a+ : a가 적어도 1개 이상(반복 - 한 번 이상 반복)
a{5} : a가 5개
a{2,5} : a가 2~5개
a{2,} : a가 2개 이상
a{,2} : a가 2개 이하

    <label>주민등록번호 입력 : </label>
    <input type="text" id="pno2">
    <button id="test5">실행확인</button>
    <script>
        document.querySelector("#test5").addEventListener('click', function(){
            // 입력 값
            let pno = document.querySelector("#pno2").value;
            // 수량 문자 적용
            let regExp = /^\d{6}-[1234]\d{6}$/;

            if(regExp.test(pno)) {
                alert('정상 입력!');
            } else {
                alert('잘못 된 입력!');
            }
        });
    </script>

 

회원가입 유효성 체크

    <form name="memberJoin" method="post">
        <label for="userid">* 아이디</label>
        <input type="text" name="userid" id="userid" required><br>
        <label for="pass">* 비밀번호</label>
        <input type="password" name="pass" id="pass" required><br>
        <label for="name">* 이름</label>
        <input type="text" name="name" id="name" required><br>
        <label for="tel1">휴대폰 번호</label>
        <input type="text" name="tel1" id="tel1" maxlength="3">-
        <input type="text" name="tel2" id="tel2" maxlength="4">-
        <input type="text" name="tel3" id="tel3" maxlength="4"><br>
        <input type="reset" value="리셋">
        <input type="submit" value="완료">
    </form>
    <script>
        document.forms.memberJoin.onsubmit = function(){
            // 1. 아이디 검사
            // 첫 글자는 반드시 영문 소문자로 시작하고
            // 영문 대소문자와 숫자로만 이루어진 6~12자 사이의 값
            if(!check(/^[a-z][A-Za-z\d]{5,11}$/
            , document.getElementById('userid')
            , "아이디는 영문 소문자로 시작하여 영문과 숫자로만 6~12자 입력"))
            return false;   // onsubmit의 기본 동작 제거로 제출되지 않음

            // 2. 비밀번호 검사
            // 소문자, 대문자, 숫자, 특수문자 모두 1개 이상 포함하며
            // 8자 이상
            if(!check(/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9]).{8,}/
            , document.getElementById('pass')
            , "비밀번호는 영문 대소문자 숫자 특수문자 포함하여 8자 이상 입력"))
                return false;

            // 3. 이름 검사
            // 2글자 이상의 온전한 한글만
            if(!check(/^[가-힣]{2,}$/, document.getElementById('name'),
            "이름은 한글로 2글자 이상 입력하세요"))
                return false;
            
            // 4. 휴대폰 번호 검사
            // 앞자리는 010, 011, 016, 017, 019만 가능 => "올바른 번호 입력하세요"
            // 두번째 자리는 3~4자리 숫자 => "번호 3자리 이상 입력하세요"
            // 세번째 자리는 4자리 숫자 => "번호 4자리로 입력하세요"
            if(!check(/^01[01679]$/, document.getElementById('tel1'),
            "올바른 번호 입력하세요"))
                return false;

            if(!check(/^\d{3,4}$/, document.getElementById('tel2'),
            "번호 3자리 이상 입력하세요"))
                return false;
            
            if(!check(/^\d{4}$/, document.getElementById('tel3'),
            "번호 4자리로 입력하세요"))
                return false;
        };

        // 유효성 검사용 함수
        function check(regExp, input, msg){
            // 전달 받은 정규 표현식과 사용자 입력 양식의 값이 패턴 일치할 경우
            if(regExp.test(input.value)) 
                return true;
            
            // 전달 받은 정규 표현식과 사용자 입력 양식의 값이 패턴 일치하지 않을 경우
            alert(msg);
            input.value = '';
            input.focus();
            return false;
        }
    </script>