본문 바로가기

웹개발 수업/JavaScript

[Day +65 / Java Script]기초(19. 정규 표현식, 20. geolocation)

210927 월

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>19_정규표현식</title>
    <style>
        .area{
            background: lightgray;
            border: 1px solid black;
            min-height: 150px;
        }
    </style>
</head>
<body>
    <h1>정규 표현식</h1>
    <p>
        특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식 언어로 
        정규 표현식을 이용하면 입력된 문자열에 대하여 특정 조건 검색, 치환 처리<br>
        복잡한 조건문 대신 간단하게 처리 가능
    </p>
    <h3>정규 표현식(Regular Expressions)의 객체 생성</h3>
    <p>
        자바스크립트에서는 RegExp 객체와 문자열 메소드를 조합해 정규 표현식 사용<br>
        정규 표현식은 패턴(pattern)과 선택적으로 사용할 수 있는 플래그(flag) 문자로 구성
    </p>
    <script>
        // 정규식 생성 문법1
        // 상황에 따라 동적으로 생성된 문자열로 정규식을 만들어야 하는 경우
        let regExp = new RegExp('pattern', 'gmi');

        // 정규식 생성 문법 2
        // 코드 작성시 이미 패턴을 알고 있을 경우 사용
        regExp = /pattern/;        // 플래그 없이
        regExp = /pattern/gmi;     // 플래그 추가

    </script>

    <h3>정규식 사용 메소드</h3>
    <p>
        <b>정규 표현식 메소드</b><br>
        1) test : 문자열에서 정규식 변수의 값과 일치하는 값이 있으면 true리턴, 없으면 false 리턴<br>
        2) exec : 문자열에서 정규식 변수의 값과 일치하는 값이 있으면 처음 매치된 문자열 반환
    </p>

    <p>
        <b>문자열 메소드</b>
        match : 문자열에서 정규식 변수의 값과 일치하는 모든 값 반환 ex) str.match(regExp)<br>
        replace : 문자열에서 정규식 변수의 값과 일치하는 부분을 새로운 값으로 변경<br>
        search : 문자열에서 정규식 변수의 값과 일치하는 부분의 시작 인덱스 반환<br>
        split : 정규식 변수에 지정된 값을 구분자로 하여 배열 생성
    </p>

    <button id = "test1">확인하기</button>
    <div id = "area1" class = "area"></div>

    <script>
          document.getElementById('test1').addEventListener('click',function() {
            // 검색 대상 문자열
            let str = 'javascript jquery ajax';

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

            // area에 표현할 html
            let html = "str : "+ str +"<br>"
                     + "regExp : /script/ <br>"
                     + "test : " + regExp.test(str) + "<br>"
                     + "exec : " + regExp.exec(str) + "<br>"
                     + "match : " + str.match(regExp) + "<br>"
                     + "replace : " + str.replace(regExp, '스크립트') + "<br>"
                     + "search : " + str.search(regExp) + "<br>"
                     + "split : " + str.split(regExp) + "<br>";

         document.getElementById('area1').innerHTML = html;
         console.log(str.split(regExp));
        });
    </script>

    <h3>메타 문자를 이용한 문자 검색, 치환</h3>
    <p>
        1) ^ : 텍스트의 시작<br>
        ex. /^a/ : 소문자 a로 시작하는 패턴<br><br>
        2) $ : 텍스트의 끝<br>
        ex. /z$/ : 소문자 z로 끝나는 패턴<br><br>
        3) [] : 범위 표현<br>
        ex. /[ab]/ : 소문자 a 또는 b 패턴,
        /[a-z]/ : 소문자 패턴, /[A-Za-z]/ : 대소문자 패턴<br><br>
        4) . : 어떤 문자가 오든 매칭<br>
        ex. /a.c/ : a와 c 사이의 아무 문자 하나가 있는 패턴<br><br>
        5) + : 앞의 문자를 1개 이상 찾음<br>
        ex. /a+/ : a 또는 aa 또는 aaa...
    </p>
    

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

            // 문자열에서 정규식과 일치하는 값이 있는지 검사
            html += "test : " + regExp.test(str) + "<br>";
            // 문자열에서 정규식과 일치하는 값이 있을 때 첫번째 값 대체
            html += "replace : " + str.replace(regExp, '(***)') + "<br><br>";
            
             // 답
            // str : javascript jquery ajax
            // regExp : /a/
            // test : true
            // replace : j(***)vascript jquery ajax


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

            // 답
            // regExp : /^j/
            // test : true
            // replace : (***)avascript jquery ajax


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


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

            // 답
            // regExp : /^[js]/
            // test : true
            // replace : (***)avascript jquery ajax


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

            // 답
            // regExp : /x$/
            // test : true
            // replace : javascript jquery aja(***)


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

            // 답
            // regExp : /^j.+x$/
            // test : true
            // replace : (***)



            regExp = /^[0-9]+$/;
            html += "regExp : " + regExp + "<br>"
                + "test : " + regExp.test(str) + "<br>"
                + "replace : " + str.replace(regExp, '(***)') + "<br><br>";
            
            // 답           
            // regExp : /^[0-9]+$/
            // test : false
            // replace : javascript jquery ajax

            regExp = /^[0-9]+$/;
            str = "1234567890";
            html += 
                "str : " + str + "<br>"
                + "regExp : " + regExp + "<br>"
                + "test : " + regExp.test(str) + "<br>"
                + "replace : " + str.replace(regExp, '(***)') + "<br><br>";

            // 답
            // str : 1234567890
            // regExp : /^[0-9]+$/
            // test : true
            // replace : (***)

            regExp = /^[0-9]+$/;
            str = "123456ㅇ7890";
            html += "str : " + str + "<br>"
                + "regExp : " + regExp + "<br>"
                + "test : " + regExp.test(str) + "<br>"
                + "replace : " + str.replace(regExp, '(***)') + "<br><br>";

            // 답            
            //  str : 123456ㅇ7890
            // regExp : /^[0-9]+$/
            // test : false
            // replace : 123456ㅇ7890


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

            // 답
            // str : JavaScript
            // regExp : /^[a-zA-z]+$/
            // test : true
            // replace : (***)


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

            // 답
            // str : JavaScript
            // regExp : /^[a-zA-Z0-9]+$/
            // test : true
            // replace : (***)


            // 한글만 입력한 경우
            regExp = /^[가-힣]+$/;
            str = "안녕하세요";
            str = "ㅎㅇ";
            html += "str : " + str + "<br>"
                + "regExp : " + regExp + "<br>"
                + "test : " + regExp.test(str) + "<br>"
                + "replace : " + str.replace(regExp, '(***)') + "<br><br>";

            // 답
            // str : 안녕하세요
            // regExp : /^[가-힣]+$/
            // test : true
            // replace : (***)

            // 답
            // str : ㅎㅇ
            // regExp : /^[가-힣]+$/
            // test : false
            // replace : ㅎㅇ
            

            // 한글만 입력한 경우
            regExp = /^[ㄱ-ㅎㅏ-ㅣ가-힣]+$/;
            str = "안녕하세요";
            str = "ㅎㅇ";
            html += "str : " + str + "<br>"
                + "regExp : " + regExp + "<br>"
                + "test : " + regExp.test(str) + "<br>"
                + "replace : " + str.replace(regExp, '(***)') + "<br><br>";

            //  답
            //  str : ㅎㅇ
            // regExp : /^[ㄱ-ㅎㅏ-ㅣ가-힣]+$/
            // test : true
            // replace : (***)

            document.getElementById('area2').innerHTML = html;
           
        });
    </script>


    <h3>플래그 문자</h3>
    <p>
        g : 전역 비교를 수행한다<br>
        i : 대소문자를 가리지 않고 비교한다<br>
        m : 여러 줄의 검사를 수행한다
    </p>
    <button id = "test3">실행확인</button>
    <div id = "area3" class = "area"></div>
    <script>
        document.getElementById('test3').addEventListener('click', function(){
            let str = 'JavaScript JQuary Ajax';
            let regExp = /a/;
            let html = "str : " + str + "<br>"
                    + "regExp : " + regExp + "<br>"
                    + "replace : " + str.replace(regExp, "($&)") + "<br><br>";
            // $& : 대체 문자열에 일치하는 전체 문자열의 복사본을 포함

            // 답
            // str : JavaScript JQuary Ajax
            // regExp : /a/
            // replace : J(a)vaScript JQuary Ajax


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

            // 답
            // regExp : /a/g
            // replace : J(a)v(a)Script JQu(a)ry Aj(a)x


            regExp = /a/gi;
            html += "regExp : " + regExp + "<br>"
                    + "replace : " + str.replace(regExp, "($&)") + "<br><br>";
            
            // 답
            // regExp : /a/gi
            // replace : J(a)v(a)Script JQu(a)ry (A)j(a)x


            str = "JavaScript\nJQuary\nAjax";
            // Q. 개행 안되는 이유
            // A? html안에서는 공백이 많이 있어도 공백은 하나로 인식되니까
            regExp = /^j/gi;
            html += "str : " + str + "<br>"
                    + "regExp : " + regExp + "<br>"
                    + "replace : " + str.replace(regExp, "($&)") + "<br><br>";
            
            regExp = /^j/gim;
            html += "str : " + str + "<br>"
                    + "regExp : " + regExp + "<br>"
                    + "replace : " + str.replace(regExp, "($&)") + "<br><br>";

            // 답(두 값 비교)
            // str : JavaScript JQuary Ajax
            // regExp : /^j/gi
            // replace : (J)avaScript JQuary Ajax

            // str : JavaScript JQuary Ajax
            // regExp : /^j/gim
            // replace : (J)avaScript (J)Quary Ajax


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

            // 답
            // str : JavaScript JQuary Ajax
            // regExp : /[^j]/gim
            // replace : J(a)(v)(a)(S)(c)(r)(i)(p)(t)( )J(Q)(u)(a)(r)(y)( )(A)j(a)(x)



            document.getElementById('area3').innerHTML = html;
        });
    </script>

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

    <h3>메타 문자를 이용한 주민번호 확인</h3>
    <label>주민번호 입력 : </label>
    <input type="text" id="pno">
    <button id="test4">실행확인</button>
    <script>
        document.getElementById('test4').addEventListener('click', function(){
            // 자리수 맞춤
            let regExp = /^......-.......$/;
            // 자리수 + 숫자만
            regExp = /^\d\d\d\d\d\d-[1234]\d\d\d\d\d\d$/;
            let pno = document.getElementById('pno').value;

            if(regExp.test(pno))
            alert('정상적으로 입력되었습니다');
            else
            alert('잘못 입력되었습니다');
        });
    </script>


    <h3>수량문자</h3>
    <p>
        a+ : a가 적어도 1개 이상(반복 - 한번 이상 반복)<br>
        a* : a가 0개 또는 여러 개(반복 여부 - 0번 또는 그 이상 반복)<br>
        a? : a가 0개 또는 1개 (존재 여부 - 존재할 수도 존재하지 않을 수도)<br>
        a{5} : a가 5개<br>
        a{2, 5} : a가 2~5개<br>
        a{2, } : a가 2개 이상<br>
        a{, 2} : a가 2개 이하
    </p>

    <label>주민번호 입력 : </label>
    <input type = "text" id = "pno2">
    <button id = "test5">실행확인</button>
    <script>
        document.getElementById('test5').addEventListener('click', function(){
            let regExp = /^\d{6}-[1234]\d{6}$/;
            // 월 : 1~12, 일 : 1~31
            // x|y : x 또는 y에 대응
            regExp = /^\d{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])-[1234]\d{6}$/;
            let pno = document.getElementById('pno2').value;

            if(regExp.test(pno))
            alert('정상적으로 입력하였습니다');
            else
            alert('잘못 입력하였습니다');

        });
    </script>

    <h3>회원 가입 유효성 체크</h3>
    <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(){
        // 아이디 검사
        // 첫 글자는 반드시 영문 소문자로 시작하고
        // 영문 대소문자와 숫자로만 이뤄진 6~12자 사이의 아이디
        // 정규 표현식을 만족할 경우 true, 불만족할 경우 false
        if(!check(/^[a-z][A-Za-z\d]{5,11}$/, document.getElementById('userid'), 
        "아이디는 영문 소문자로 시작하여 영문과 숫자로만 6~12자 입력하세요"))
            return false;   // submit 되지 않도록 return false 처리


        // 비밀번호 검사
        // 소문자, 대문자, 숫자, 특수문자 모두 포함하여 8자 이상
        // (?=) 전방 탐색은 패턴과 일치하는지 확인하지만 값으로 리턴하지 않는 정규식 패턴
        if(!check(/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9]).{8,}/,
                document.getElementById('pass'),
                "비밀번호는 영문 대소문자 숫자 특수문자를 모두 하나 이상 포함하여 8~20자 이상 입력하세요"))
            return false;

            // 이름 검사
            // 2글자 이상으로 온전한 한글만
            // 통과하지 못하면 "이름은 한글로 2글자 이상 입력하세요"
            if(!check(/^[가-힣]{2,}$/,
            document.getElementById('name'),
            "이름은 한글로 2글자 이상 입력하세요"))
            return false;

            // 휴대폰 번호 검사
            // 앞자리는 010, 011, 016, 017, 019만 가능
            // 두번째 자리는 3~4자리 숫자
            // 세번째 자리는 4자리 숫자
            if(!check(/^01[01679]$/,
            document.getElementById('tel1'),
            "010, 011, 016, 017, 019만 입력 가능합니다"))
            return false;

            if(!check(/^[0-9]{3,4}$/,
            // \d{3, 4}도 가능
            document.getElementById('tel2'),
            "3~4글자 입력하세요"))
            return false;

            if(!check(/^[0-9]{4}$/,
            document.getElementById('tel3'),
            "4글자 입력하세요"))
            return false;
        };

        function check(regExp, input, msg){
            // 정규 표현식 만족할 경우 true 리턴
            if(regExp.test(input.value)) return true;
            // 정규 표현식 불만족할 경우
            alert(msg);

            input.value= '';
            input.focus();
            return false;
        }
    </script>

</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>20_geolocation</title>
    <style>
        .div{
            width : 500px;
            min-height: 100px;
            border : 1px solid black;
        }
    </style>
</head>
<body>
    <h1>geolocation</h1>

    <p>
        위치 정보 API를 사용하기 위해 navigator.geolocation 내장 객체를 이용해야 함
    </p>

    <h2>geolocation 지원 여부 확인</h2>
    <button id = "btn1">geolocation navigator</button>
    <script>
        document.getElementById('btn1').addEventListener('click', supportGeolocation);

        function supportGeolocation(){
            if(window.navigator.geolocation)
            // window는 최상위 객체이므로 생략 가능
            alert('geolocation을 지원합니다.')
            else
            alert('geolocation을 지원하지 않습니다');
        };
    </script>

    <h2>위도/경도 확인</h2>
    <div class="div" id="comment"></div>
    <button id="btn2">위치 정보 확인</button>
    <script>
        document.getElementById('btn2').addEventListener('click', getGeolocation);

        function getGeolocation(){
                if(window.navigator.geolocation){
                // navigator.geolocation.getCurrentPosition(successCallback, [errorCallback]);
                // : 현재 위치 정보를 반환하는 메소드 (성공시, 실패시)
                navigator.geolocation.getCurrentPosition(showPosition, handleError);
                }else{
                    document.getElementById('comment').innerHTML
                    = 'geolocation을 지원하지 않는 브라우저입니다';
                }
            }

            // successCallback
            function showPosition(position){
                document.getElementById('comment').innerHTML
                = '위도 : ' + position.coords.latitude + "<br>경도 : " + position.coords.longitude;            }

            // errorCallback
            function handleError(error){
                // error.code
                if(error.code === error.PERMISSION_DENIED){
                    alert('사용자가 위치 정보에 대한 접근을 막은 경우');
                }else if(error.code === error.POSITION_UNAVAILABLE){
                    alert('네트워크 또는 GPS에 연결할 수 없는 경우')
                }else if(error.code === TIMEOUT){
                    alert('사용자의 위치 정보를 계산하는데 시간이 초과한 경우');
                }else if(error.code === error.UNKNOWN_ERROR){
                    alert('그 외 알 수 없는 문제가 생긴 경우');
                }
            }
    </script>

</body>
</html>