JS 정규표현식 객체 생성 방법
1. const regEx = new RegExp("정규표현식");
2. const regEx = /정규표현식/;
정규표현식 객체가 제공하는 메서드(함수)
1. regEx.test(문자열)
-> 문자열이 정규표현식 패턴에 부합하면 true, 아니면 false
2. regEx.exec(문자열)
-> 문자열이 정규표현식 패턴에 부합하면
첫 번째 매칭되는 문자열을 반환,
없으면 null 반환
정규 표현식의 메타 문자
문자열의 패턴을 나타내는 문자.
문자마다 지정된 특별한 뜻이 담겨있다.
- a (일반문자열) : 문자열 내에 a라는 문자열이 존재하는 검색
- [abcd] : 문자열 내에 a,b,c,d 중 하나라도 일치하는 문자가 있는지 검색
- ^(캐럿) : 문자열의 시작을 의미
- $(달러) : 문자열의 끝을 의미
- \w (word, 단어) : 아무 글자(단, 띄어쓰기, 특수문자, 한글 X)
- \d (digit, 숫자) : 아무 숫자(0~9 중 하나)
- \s (space, 공간) : 아무 공백 문자(띄어쓰기, 엔터, 탭 등)
- [0-9] : 0부터 9까지 모든 숫자
- [ㄱ-힣] : ㄱ부터 힣까지 모든 한글
- [가-힣] : 가부터 힣까지 모든 한글(자음만, 모음만 있는 경우 제외)
- [a-z] : 모든 영어 소문자
- [A-Z] : 모든 영어 대문자
특수문자의 경우 각각을 입력하는 방법밖엔 없음
단, 메타문자와 중복되는 특수문자는
앞에 (백슬래시)를 추가하여 탈출 문자(Escape)로 만들어 사용
- 수량 관련 메타 문자
a{5} : a문자가 5개 존재 == aaaaa
a{2,5} : a가 2개 이상 5개 이하 == aa, aaa, aaaa, aaaaa
a{2,} : a가 2개 이상
a{,5} : a가 5개 이하
- * : 0개 이상 == 0번 이상 반복 == 있어도되고, 없어도 되고
- + : 1개 이상 == 1번 이상 반복
- ? : 0개 또는 1개
- . : 1칸 (개행문자를 제외한 문자 하나)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!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>회원가입</title>
<link rel="stylesheet" href="/resources/css/member/signUp-style.css">
</head>
<body>
<main>
<%-- header.jsp include --%>
<%-- 다른 jsp 코드를 현재 위치에 포함 webapp부터의 jsp경로를 작성 --%>
<jsp:include page="/WEB-INF/views/common/header.jsp"/>
<section class="signUp-content">
<form action="/member/signUp" method="POST" name="signUpFrm" id="signUpFrm">
<!-- 이메일 입력 -->
<label for="memberEmail">
<span class="required">*</span> 아이디(이메일)
</label>
<div class="signUp-input-area">
<input type="text" name="memberEmail" id="memberEmail"
placeholder="아이디(이메일)" maxlength="30" autocomplete="off">
<button id="sendAuthKeyBtn" type="button">인증번호 받기</button>
</div>
<span class="signUp-message" id="emailMessage">메일을 받을 수 있는 이메일을 입력해주세요.</span>
<!-- 인증번호 입력 -->
<label for="emailCheck">
<span class="required">*</span> 인증번호
</label>
<div class="signUp-input-area">
<input type="text" name="authKey" id="authKey" s placeholder="인증번호 입력" maxlength="6" autocomplete="off" >
<button id="checkAuthKeyBtn" type="button">인증하기</button>
</div>
<span class="signUp-message" id="authKeyMessage"></span>
<!-- 인증번호가 일치하지 않습니다 -->
<!-- 비밀번호/비밀번호 확인 입력 -->
<label for="memberPw">
<span class="required">*</span> 비밀번호
</label>
<div class="signUp-input-area">
<input type="password" name="memberPw" id="memberPw"
placeholder="비밀번호" maxlength="20" >
</div>
<div class="signUp-input-area">
<input type="password" name="memberPwConfirm" id="memberPwConfirm"
placeholder="비밀번호 확인" maxlength="20" >
</div>
<span class="signUp-message" id="pwMessage">영어,숫자,특수문자(!,@,#,-,_) 6~20글자 사이로 입력해주세요.</span>
<!-- 닉네임 입력 -->
<label for="memberNickname">
<span class="required">*</span> 닉네임
</label>
<div class="signUp-input-area">
<input type="text" name="memberNickname" id="memberNickname" placeholder="닉네임" maxlength="10" >
</div>
<span class="signUp-message" id="nickMessage">한글,영어,숫자로만 2~10글자</span>
<!-- 전화번호 입력 -->
<label for="memberTel">
<span class="required">*</span> 전화번호
</label>
<div class="signUp-input-area">
<input type="text" name="memberTel" id="memberTel" placeholder="(- 없이 숫자만 입력)" maxlength="11">
</div>
<span class="signUp-message" id="telMessage">전화번호를 입력해주세요.(- 제외)</span>
<!-- 주소 입력 -->
<label for="memberAddress">주소</label>
<div class="signUp-input-area">
<input type="text" name="memberAddress" placeholder="우편번호" maxlength="6" id="sample6_postcode">
<button type="button" onclick="sample6_execDaumPostcode()">검색</button>
</div>
<div class="signUp-input-area">
<input type="text" name="memberAddress" placeholder="도로명/지번 주소" id="sample6_address">
</div>
<div class="signUp-input-area">
<input type="text" name="memberAddress" placeholder="상세 주소" id="sample6_detailAddress">
</div>
<button id="signUpBtn">가입하기</button>
</form>
</section>
</main>
<%-- footer.jsp include --%>
<jsp:include page="/WEB-INF/views/common/footer.jsp"/>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
function sample6_execDaumPostcode() {
new daum.Postcode({
oncomplete: function(data) {
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 각 주소의 노출 규칙에 따라 주소를 조합한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
var addr = ''; // 주소 변수
//사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
addr = data.roadAddress;
} else { // 사용자가 지번 주소를 선택했을 경우(J)
addr = data.jibunAddress;
}
// 우편번호와 주소 정보를 해당 필드에 넣는다.
document.getElementById('sample6_postcode').value = data.zonecode;
document.getElementById("sample6_address").value = addr;
// 커서를 상세주소 필드로 이동한다.
document.getElementById("sample6_detailAddress").focus();
}
}).open();
}
</script>
<script src="/resources/js/member/signUp.js"></script>
</body>
</html>
// 회원가입 js
/* 정규 표현식(Regular Expression)
https://regexper.com/
https://regexr.com/
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/%EC%A0%95%EA%B7%9C%EC%8B%9D
- 특정한 규칙을 가진 문자열 집합을 표현하는데 사용하는 형식 언어
- 문자열에 대한 검색, 일치 여부, 치환 등을 수행할 수 있음
*** JS 정규표현식 객체 생성 방법 ***
1. const regEx = new RegExp("정규표현식");
2. const regEx = /정규표현식/;
*** 정규표현식 객체가 제공하는 메서드(함수) ***
1. regEx.test(문자열)
-> 문자열이 정규표현식 패턴에 부합하면 true, 아니면 false
2. regEx.exec(문자열)
-> 문자열이 정규표현식 패턴에 부합하면
첫 번째 매칭되는 문자열을 반환,
없으면 null 반환
*** 정규 표현식의 메타 문자***
문자열의 패턴을 나타내는 문자.
문자마다 지정된 특별한 뜻이 담겨있다.
a (일반문자열) : 문자열 내에 a라는 문자열이 존재하는 검색
[abcd] : 문자열 내에 a,b,c,d 중 하나라도 일치하는 문자가 있는지 검색
^(캐럿) : 문자열의 시작을 의미
$(달러) : 문자열의 끝을 의미
\w (word, 단어) : 아무 글자(단, 띄어쓰기, 특수문자, 한글 X)
\d (digit, 숫자) : 아무 숫자(0~9 중 하나)
\s (space, 공간) : 아무 공백 문자(띄어쓰기, 엔터, 탭 등)
[0-9] : 0부터 9까지 모든 숫자
[ㄱ-힣] : ㄱ부터 힣까지 모든 한글
[가-힣] : 가부터 힣까지 모든 한글(자음만, 모음만 있는 경우 제외)
[a-z] : 모든 영어 소문자
[A-Z] : 모든 영어 대문자
* 특수문자의 경우 각각을 입력하는 방법밖엔 없음
단, 메타문자와 중복되는 특수문자는
앞에 \(백슬래시)를 추가하여 탈출 문자(Escape)로 만들어 사용
* 수량 관련 메타 문자
a{5} : a문자가 5개 존재 == aaaaa
a{2,5} : a가 2개 이상 5개 이하 == aa, aaa, aaaa, aaaaa
a{2,} : a가 2개 이상
a{,5} : a가 5개 이하
* : 0개 이상 == 0번 이상 반복 == 있어도되고, 없어도 되고
+ : 1개 이상 == 1번 이상 반복
? : 0개 또는 1개
. : 1칸 (개행문자를 제외한 문자 하나)
*/
// JS객체 : "{"K":V, "k":V}" (Map 형식)
// 특징
// 1) 원하는 value를 얻어오는 방법
// - 객체명.key
// - 객체명 ["key"]
// 2) 객체에 특징 Key가 존재하지 않으면 추가 할 수 있다
// ex ) const obj = {"a":1 , "b":2}
// obj.c = 3 // => {"a":1 , "b":2, "c":3}
// 3) 객체의 특정 key를 삭제 할 수 있다.(Delete 연산자)
// ex) const obj = {"a":1 , "b":2}
// delete obj.b; {"a":1}
/*유효성 검사 진행 여부 확인용 객체*/
// => 모든 value가 true인 경우만 회원가입 진행
const checkObj = {
"memberEmail" : false
,"memberPw": false
, "memberPwConfirm" : false
, "memberNickname" : false
, "memberTel" : false
}
//이메일 유효성 검사
const memberEmail = document.getElementById("memberEmail");
const emailMessage = document.getElementById("emailMessage");
//이메일이 입력될 때 마다
memberEmail.addEventListener("input", ()=>{
//입력된 이메일이 없을 경우
if(memberEmail.value.trim().length == 0 ){
emailMessage.innerText ="";
emailMessage.innerText = "메일을 받을 수 있는 이메일을 입력해주세요";
emailMessage.classList.remove("confirm", "error");
checkObj.memberEmail = false; //빈칸 == 유효 X
return;
}
// 정규 표현식을 이용해서 유효한 형식인지 판별
// 1) 정규표현식 객체 생성
const regEx = /^[A-Za-z\d\-\_]{4,}@[가-힣\w\-\_]+(\.\w+){1,3}$/
//2)입력 받은 이메일과 정규식 일치하는지 여부 판별
if(regEx.test(memberEmail.value)){//유효한 경우
emailMessage.innerText="유효한 이메일 입니다.";
emailMessage.classList.remove("error");
emailMessage.classList.add("confirm");
checkObj.memberEmail = true; // 유효 O
}else{//유효하지 않은 경우
emailMessage.innerText="유효하지 않은 이메일 입니다."
emailMessage.classList.remove("confirm");
emailMessage.classList.add("error");
checkObj.memberEmail = false; //유효 X
}
})
// 비밀번호 / 비밀번호 확인 유효성 검사
const memberPw = document.getElementById("memberPw");
const memberPwConfirm = document.getElementById("memberPwConfirm");
const pwMessage = document.getElementById("pwMessage")
// 비밀번호 입력시 유효성 검사
memberPw.addEventListener("input", ()=>{
if(memberPw.value.trim().length == 0 ){
memberPw.value="";
pwMessage.innerText="영어,숫자,특수문자(!,@,#,-,_) 6~20글자 사이로 입력해주세요."
pwMessage.classList.remove("confirm","error"); //검정글씨
checkObj.memberPw = false
return;
}
// 정규표현식을 이용한 비밀번호 유효성 검사
//영어 숫자, 특수 문자(!,@,#,-,_) 6~20글자사이
const regEx = /^[A-Za-z0-9\!\@\#\-\_]{6,20}$/
// 입력한 비밀번호가 유효한 경우
if(regEx.test(memberPw.value) ){
checkObj.memberPw = true;
// 비밀번호가 유효하게 작성된 상태에서
// 비밀번호 확인이 입력되지 않았을 때
if(memberPwConfirm.value.trim().length ==0){
pwMessage.innerText="유효한 비밀번호 형식입니다";
pwMessage.classList.add("confirm");
pwMessage.classList.remove("error");
}else{
// 비밀번호가 유효하게 작성된 상태에서
// 비밀번호 확인이 입력되어 있을 때
// 비밀번호 == 비밀번호 확인 (같은경우)
if(memberPwConfirm.value == memberPw.value){
pwMessage.innerText="비밀번호가 일치 합니다.";
pwMessage.classList.add("confirm");
pwMessage.classList.remove("error");
checkObj.memberPwConfirm = true;
}else{ //다른 경우
pwMessage.innerText="비밀번호가 일치하지 않습니다.";
pwMessage.classList.remove("confirm");
pwMessage.classList.add("error");
checkObj.memberPwConfirm = false;
}
}
}else{
//유효하지 않은 경우
pwMessage.innerText="비밀번호 형식이 유효 하지 않습니다.";
pwMessage.classList.add("error");
pwMessage.classList.remove("confirm");
checkObj.memberPw = false;
}
})
//비밀번호 확인 유효성 검사
memberPwConfirm.addEventListener("input", ()=>{
if(checkObj.memberPw){ //비밀번호가 유효하게 작성된 경우에
//비밀번호 == 비밀번호 확인(같을 경우)
if(memberPwConfirm.value == memberPw.value){
pwMessage.innerText="비밀번호가 일치 합니다.";
pwMessage.classList.add("confirm");
pwMessage.classList.remove("error");
checkObj.memberPwConfirm = true;
}else{ //다른 경우
pwMessage.innerText="비밀번호가 일치하지 않습니다.";
pwMessage.classList.remove("confirm");
pwMessage.classList.add("error");
checkObj.memberPwConfirm = false;
}
}else{ //비밀번호가 유효하지 않은 경우
checkObj.memberPwConfirm = false;
}
})
// 닉네임 유효성 검사
const memberNickname = document.getElementById("memberNickname");
const nickMessage = document.getElementById("nickMessage");
//닉네임이 입력이 되었을 때
memberNickname.addEventListener("input", ()=>{
// 닉네임이 입력되지 않은 경우
if(memberNickname.value.trim().length == 0){
nickMessage.innerText = "한글,영어,숫자로만 2~10글자"
nickMessage.classList.remove("error", "confirm");
checkObj.memberNickname=false;
memberNickname.value="";
return;
}
//정규표현식으로 유효성 검사
const regEx = /^[A-Za-z가-힣0-9]{2,10}$/
if(regEx.test(memberNickname.value)){ //유효O
nickMessage.innerText="유효한 닉네임입니다.";
nickMessage.classList.add("confirm");
nickMessage.classList.remove("error");
checkObj.memberNickname=true;
}else{ //무효
nickMessage.innerText="닉네임이 유효하지 않습니다.";
nickMessage.classList.add("error");
nickMessage.classList.remove("confirm");
checkObj.memberNickname=false;
}
})
// 전화번호 유효성 검사
const memberTel= document.getElementById("memberTel");
const telMessage = document.getElementById("telMessage");
memberTel.addEventListener("input", ()=>{
if(!memberTel.value.trim().length ==0){
// 전화 번호가 입력되었을 때
// 정규식 유효성 검사
const regEx = /^0(1[01679]|2|[3-6][1-5]|70)\d{3,4}\d{4}$/;
if(regEx.test(memberTel.value)){ //유효O
telMessage.innerText="유효한 전화번호입니다.";
telMessage.classList.add("confirm");
telMessage.classList.remove("error");
checkObj.memberTel=true;
}else{ //무효
telMessage.innerText="전화번호이 유효하지 않습니다.";
telMessage.classList.add("error");
telMessage.classList.remove("confirm");
checkObj.memberTel=false;
}
}else{
// 전화번호가 입력되지 않았을 때
telMessage.innerText = "전화번호를 입력해주세요.(- 제외)"
telMessage.classList.remove("confirm", "error");
checkObj.memberTel=false;
}
})
// 회원가입 form태그가 제출 되었을 때
document.getElementById("signUpFrm").addEventListener("submit", (e)=>{
//checkObj에 모든 value가 true인지 검사
//(배열용 for 문)
// for...of : 향상된 for 문
// -> interator (반복자) 속성을 지닌 배열, 유사배열 사용 가능
//(객체용 for문)
// for... in :
// -> JS 객체가 가지고 있는 key를 순서대로 하나씩 꺼내는 반복문
for( let key in checkObj ){
if(!checkObj[key]){ // 각 key에 대한 value(true/false)를 얻어와
// false인 경우 == 유효하지 않다!
switch(key){
case "memberEmail" : alert("이메일이 유효하지 않습니다."); break;
case "memberPw" : alert("비밀번호가 유효하지 않습니다."); break;
case "memberPwConfirm" : alert("비밀번호가 확인되지 않았습니다"); break;
case "memberNickname" : alert("닉네임이 유효하지 않습니다."); break;
case "memberTel" : alert("전화번호가 유효하지 않습니다."); break;
}
// 유효하지 않은 input태그로 focus이동
// -key를 input의 id와 똑같이 설정
document.getElementById(key).focus();
// form 태그 기본 이벤트 제거
e.preventDefault();
return; //함수 종료
}
}
})