JavaScript의 정규표현식에 대해 알아보자
정규표현식
✔️ *정규 표현식(REGEX / REGEXP : Regular Expression)이란?
특정 패턴을 가진 문자열을 찾거나 또는 찾아서 변경(치환)할 때 사용하는 형식 언어
정규 표현식을 이용하면 문자열에 대해 특정 패던 조건 검사 시 또는 치환 시 복잡한 조건을 제시할 필요가 없어 간단하게 처리 가능
자바스크립트 뿐만 아니라 자바나 오라클 등 다른 언어에서도 사용 가능
정규 표현식 객체 생성 및 정규 표현식과 관련한 메소드들
👉🏻 정규 표현식 객체 생성 == 정규식 변수를 선언
정규 표현식을 제시하려면 우선적으로 정규 표현식 객체를 생성해 줘야 함
- 방법 1: 기본 내장 클래스 RegExp의 객체를 생성하고 그 안에 문자열 제시
- 방법 2: 특정 패턴인 / /(슬래시) 안에 문자열 가두기
👉🏻 정규 표현식 객체에서 제공하는 메소드 (정규식.xxx(문자열)) - 주어(기준)가 정규식
- 정규식.test(문자열): 문자열로부터 정규식 값과 일치하는 값이 있으면 true, 없으면 false 반환
- 정규식.exec(문자열): 문자열로부터 정규식 값과 일치하는 값이 있으면 처음 매칭된 그 문자열을 반환, 없으면 null 반환
👉🏻 문자열 객체에서 제공하는 메소드 (문자열.xxx(정규식)) - 주어(기준)가 비교할 문자열
- 문자열.match(정규식): 문자열에서 정규식 값과 일치하는 값을 찾아서 반환
- 문자열.search(정규식): 문자열에서 정규식 값과 일치하는 값의 시작 인덱스를 반환 (0에서 시작), 일치하는 값이 없다면 -1을 반환
- 문자열.replace(정규식, 바꿀값): 문자열에서 정규식 값과 일치하는 첫 번째 부분만 바꿀 값으로 변환
- 문자열.split(정규식): 정규식에 지정된 값을 구분자로 하여 쪼개진 값들이 담겨 있는 배열을 반환
✔️ 특히 test(), replace()는 매우 자주 쓰이므로 꼭! 알고 넘어가기
<button onclick="test1();">실행확인</button>
<div id="area1" class="area"></div>
<script>
function test1() {
var regExp = new RegExp("script"); // 방법1. 기본 내장 클래스 RegExp의 객체를 생성하고 그 안에 문자열 제시
var regExp2 = /script/; // 방법2. 특정패턴인 / /(슬래시) 안에 문자열 가두기
console.log(regExp);
console.log(regExp2);
// 결과 똑같음!
}
</script>
<문자열 제시하여 메소드 테스트>
<button onclick="test1();">실행확인</button>
<div id="area1" class="area"></div>
<script>
function test1() {
// 정규 표현식 객체 생성
var regExp = new RegExp("script"); // 방법1. 기본 내장 클래스 RegExp의 객체를 생성하고 그 안에 문자열 제시
var regExp2 = /script/; // 방법2. 특정패턴인 / /(슬래시) 안에 문자열 가두기
// 비교할 문자열
var str1 = "javascript jquery ajax";
var str2 = "java oracle html css";
var area1 = document.getElementById("area1");
// 검사하고자 하는 패턴 /script/
// 정규식 객체에서 제공하는 메소드들 (test, exec)
area1.innerHTML = "regExp.test(str1): " + regExp.test(str1) + "<br>"; // true
area1.innerHTML += "regExp.test(str2): " + regExp.test(str2) + "<br>"; // false
area1.innerHTML = "regExp.exec(str1): " + regExp.exec(str1) + "<br>"; // script
area1.innerHTML += "regExp.exec(str2): " + regExp.exec(str2) + "<br>"; // null
// 문자열 객체에서 제공하는 메소드들 (match, search, replace, split)
area1.innerHTML += "<hr>";
area1.innerHTML += "str1.match(regExp): " + str1.match(regExp) + "<br>"; // script
area1.innerHTML += "str1.match(regExp): " + str2.match(regExp) + "<br>"; // null
area1.innerHTML += "str1.search(regExp): " + str1.search(regExp) + "<br>"; // 4
area1.innerHTML += "str2.search(regExp): " + str2.search(regExp) + "<br>"; // -1
area1.innerHTML += "str1.replace(regExp, '스크립트'): " + str1.replace(regExp, "스크립트") + "<br>";
// java스크립트 jquery ajax
area1.innerHTML += "str1.split(regExp): " + str1.split(regExp) + "<br>";
// java, jquery ajax => 0번, 1번 인덱스로 나뉘어서 배열로 반환됨
}
</script>
메타 문자
👉🏻 메타 문자를 이용해서 정규식으로 검색 조건으로 삼을 특정 패턴을 제시 가능
문자열이 해당 정규식으로 제시한 특정 패턴에 만족하는지 test()를 통해서 검사하거나 replace()를 통해 치환 가능
✔️ ^ : 시작을 의미 => css의 속성선택자 중 ^= : 해당 값으로 "시작"하는 경우였음
✔️ [] : [] 내의 문자 중 하나라도 존재할 경우를 의미
✔️ $ : 끝을 의미
✔️ . : 개행문자를 제외한 모든 문자 (영문자, 숫자, 한글, 특수문자)
✔️ + : 한 글자 이상(0글자 X)
*추가적인 메타 문자
✔️ \d : 숫자 한 글자 ([0-9])
✔️ \D : 숫자를 제외한 모든 글자 한 글자
✔️ \w : 영문자, 숫자, _ 중 한 글자
✔️ \W : 영문자, 숫자, _를 제외한 모든 글자 중 한 글자
✔️ \s : 공백 문자 한 글자(띄어쓰기, 탭, 줄 바꿈)
✔️ \S : 공백문자를 제외한 모든 문자 중 한 글자
*수량 문자
✔️ + : 1글자 이상 (적어도 1글자는 반드시 있어야 함)
✔️ * : 0글자 이상 (0글자도 가능하다라는 뜻)
✔️ ? : 0글자 또는 1글자 (2글자 이상은 불가능하다라는 뜻)
✔️ {n} : n글자
✔️ {n, m} : n글자 이상, m 글자 이하
✔️ {n,} : n 글자 이상 (상한값 없음)
✔️ {,m} : m 글자 이하 (하한값 없음)
* 그룹핑
✔️ (경우1|경우2|...)
<button onclick="test2();">실행확인</button>
<div id="area2" class="area"></div>
<script>
function test2() {
var area2 = document.getElementById("area2");
// 비교할 문자열
var str = "javascript jquery ajax";
// 메타문자 없는 경우
var regExp = /a/;
area2.innerHTML = "/a/ : " + regExp.test(str) + "<br>"; // true
area2.innerHTML += "/a/ : " + str.replace(regExp, "(***)") + "<br>";
// j(***)vascript jquery ajax => 첫 번째 a만 (***)으로 치환됨
// 기본적으로 replace는 치환 시 일치하는 값들 중에서 "첫 번째 값"만 치환함
// 메타 문자 있는 경우
// 1. ^ : 시작을 의미 => css의 속성선택자 중 ^= : 해당 값으로 "시작"하는 경우였음
regExp = /^j/; // 소문자 j로 시작하는 경우
area2.innerHTML += "<hr>";
area2.innerHTML += "/^j/ : " + regExp.test(str) + "<br>"; // true
area2.innerHTML += "/^j/ : " + str.replace(regExp, "(***)") + "<br>"; // (***)avascript jquery ajax
// 2. [] : [] 내의 문자 중 하나라도 존재할 경우를 의미
regExp = /[abc]/; // 특정 문자열 중 a 또는 b 또는 c가 하나라도 존재할 경우
area2.innerHTML += "<hr>";
area2.innerHTML += "/[abc]/ : " + regExp.test(str) + "<br>"; // true
area2.innerHTML += "/[abc]/ : " + str.replace(regExp, "(***)") + "<br>"; // j(***)vascript jquery ajax
regExp = /[kh]/;
area2.innerHTML += "/[kh]/ : " + regExp.test(str) + "<br>"; // false
// 1, 2 세트로 묶어서
regExp = /^[jsa]/; // 시작값이 j 또는 s 또는 a인지 비교할 목적의 패턴
area2.innerHTML += "<hr>";
area2.innerHTML += "/[jsa]/ : " + regExp.test(str) + "<br>"; // true
area2.innerHTML += "/[jsa]/ : " + str.replace(regExp, "(***)") + "<br>"; // (***)avascript jquery ajax
// 3. $ : 끝을 의미
regExp = /x$/; // x로 끝나는지
area2.innerHTML += "<hr>";
area2.innerHTML += "/x$/ : " + regExp.test(str) + "<br>"; // true
area2.innerHTML += "/x$/ : " + str.replace(regExp, "(***)") + "<br>"; // javascript jquery aja(***)
// 1, 2, 3 세트로 묶어서
// 시작값은 j이고 끝값은 x인지 확인
regExp = /^jx$/;
area2.innerHTML += "/^jx$/ : " + regExp.test(str) + "<br>"; // false
// /^jx$/: 현재 이 패턴에 만족하는 문자열은 무조건 "jx"임
// 4. . : 개행문자를 제외한 모든 문자 (영문자, 숫자, 한글, 특수문자)
// 5. + : 한 글자 이상(0글자 X)
// .+ : 어떤 문자든지 한 글자 이상인 경우 (단, 개행문자는 제외)
regExp = /^j.+x$/;
area2.innerHTML += "/^j.+x$/ : " + regExp.test(str) + "<br>"; // true
area2.innerHTML += "/^j.+x$/ : " + str.replace(regExp, "(***)") + "<br>"; // (***)
// 시작부터 끝까지 오로지 숫자값으로만 이루어진 경우
// (숫자의 개수는 상관없음! 단, 적어도 한 글자는 무조건 있어야 함)
regExp = /^[0123456789]+$/; // 해당 목록들 중에 하나라도 존재할 경우
regEXP = /^[0-9]+$/; // 같은 의미임!
area2.innerHTML += "<hr>";
area2.innerHTML += "/^[0123456789]+&/ : " + regExp.test("5432402") + "<br>"; // true
area2.innerHTML += "/^[0123456789]+&/ : " + regExp.test("24328가나다!abc") + "<br>"; // false
// 시작부터 끝까지 오로지 영문자, 숫자로만 이루어진 경우
// (문자의 개수는 상관없음! 단, 적어도 한 글자는 무조건 있어야 함)
regExp = /^[a-zA-Z0-9]+$/;
area2.innerHTML += "<hr>";
area2.innerHTML += "/^[a-zA-Z0-9]$/ : " + regExp.test("JavaScript123") + "<br>"; // true
area2.innerHTML += "/^[a-zA-Z0-9]$/ : " + regExp.test("Ja!Va!!스크립트000") + "<br>"; // false
// 시작부터 끝까지 오로지 한글(자음만, 모음만, 결합)로만 이루어짐
// (문자의 개수는 상관없음! 단, 적어도 한 글자는 무조건 있어야 함)
regExp = /^[ㄱ-ㅎㅏ-ㅣ가-힣]+$/;
area2.innerHTML += "<hr>";
area2.innerHTML += "/^[ㄱ-ㅎㅏ-ㅣ가-힣]$/ : " + regExp.test("자바스크립트에레레레ㅔ") + "<br>"; // true
/*
regExp = /^[ㄱ-ㅎㅏ-ㅣ가-힣]$/;
area2.innerHTML += "<hr>";
area2.innerHTML += "/^[ㄱ-ㅎㅏ-ㅣ가-힣]$/ : " + regExp.test("자") + "<br>"; // true
area2.innerHTML += "/^[ㄱ-ㅎㅏ-ㅣ가-힣]$/ : " + regExp.test("자바스크립트에레레레ㅔ") + "<br>"; // false
*/
// 한글 이름인지 검사
// 모든 글자가 결합된 한글 형태
// 성 + 이름 => 최소 2글자 이상
regExp = /^[가-힣]{2,}$/;
var name = prompt("이름을 입력하세요");
if(regExp.test(name)) {
alert("반갑습니다! 환영합니당!");
} else {
alert("유효한 형식의 이름을 입력하세요.");
}
/*
regExp = /[0-9]/;
area2.innerHTML += regExp.test("123456") + "<br>"; // true
area2.innerHTML += regExp.test(123456) + "<br>"; // true
*/
}
</script>
<정리>
*플래그 문자
👉🏻 /정규표현식/ 뒤에 작성하는 정규 표현식을 보조해 주는 문자
여러 개 제시 가능, 순서 상관없음
✔️ i: 대소문자를 가리지 않고 비교를 수행하겠음
✔️ g: 문자열 내의 모든 패턴을 찾겠음 (즉, 전역으로 비교하겠다.)
✔️ m: 여러 줄 비교를 수행하겠음 (== 문자열 안에 개행문자가 포함되더라도 비교)
<button onclick="test3();">실행확인</button>
<script>
function test3() {
// 1. i: 대소문자를 가리지 않고 비교를 수행
// 영문자(대문자, 소문자) 또는 숫자로만 이루어져야 함
// 단, 글자 수는 상관없고 무조건 한 글자 이상이어야 함
// 맨 첫 글자는 무조건 영문자여야 함
// var regExp = /^[a-zA-Z][a-zA-Z0-9]+$/;
var regExp = /^[a-zA-Z][a-zA-Z0-9]+$/i;
console.log(regExp.test("abc123")); // true
console.log(regExp.test("1ABCd")); // false
// 2. g: 전역으로 비교를 모두 수행
// => 맨 첫 글자만 치환해 주는 replace 메소드와 주로 쓰임
var str = "JavaScript JQuery Ajax"
regExp = /a/;
console.log("/a/ : " + str.replace(regExp, "(***)")); // J(***)vaScript JQuery Ajax
regExp = /a/g;
console.log("/a/g : " + str.replace(regExp, "(***)")); // J(***)v(***)Script JQuery Aj(***)x
// 대문자 A도 같이 치환하고 싶을 경우
regExp = /a/ig;
console.log("/a/ig : " + str.replace(regExp, "(***)")); // J(***)v(***)Script JQuery (***)j(***)x
// 3. m: 여러 줄 비교를 수행 (== 문자열 안에 개행문자가 포함되더라도 비교)
str = "JavaScript\nJQuery\nAjax";
regExp = /^J/;
console.log("/^J/ : " + str.replace(regExp, "(***)"));
regExp = /^J/g;
console.log("/^J/g : " + str.replace(regExp, "(***)")); // (***)avaScript
// JQuery
// Ajax
// 개행문자가 포함된 경우에는 g가 적용되지 않음
regExp = /^J/gm;
console.log("/^J/gm : " + str.replace(regExp, "(***)")); // (***)avaScript
// (***)Query
// Ajax
}
</script>
정규 표현식을 가지고 주민번호 확인 패턴 만들기
주민번호 : <input type="text" placeholder="- 포함해서 입력하시오" id="pno">
<button onclick="test4();">확인</button>
<script>
function test4() {
// 사용자가 입력한 주민번호 값
var value = document.getElementById("pno").value;
// 1단계: 6글자-7글자
// . : 개행문자를 제외한 모든 문자 (영문, 숫자, 한글, 특수문자) 중 "한 글자"
var regExp = /^......-.......$/;
// 숫자 외에 다른 문자가 와도 글자 수만 맞으면 정상 입력으로 간주
// 성별 자리에 해당하는 부분에 1, 2, 3, 4가 아닌 다른 값이 오더라도 정상 입력으로 간주
// 2단계: 숫자여야 함
regExp = /^[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9]$/
regExp = /^\d{6}-\d{7}$/;
// 3단계: 성별 자리에 해당하는 부분에 1, 2, 3, 4만 들어가야 함
regExp = /^\d{6}-[1-4]\d{6}$/;
// 날짜 형식에 맞지 않는 숫자가 들어가더라도 정상 입력으로 간주 (ex: 880834)
// 4단계: 생년월일 중 월(01 ~ 12)을 체크
// 일(01 ~ 31)을 체크
/*
앞의 6글자 중
- 생년(두 자리) : \d{2}
아무 숫자로만 두 자리를 채우면 됨
- 월(두 자리) : (경우1|경우2|...) 그룹핑 => (0[1-9]|1[0-2])
01, 02, 03, 04, ... , 12
앞자리가 0인 경우 뒷자리는 1 ~ 9까지 가능 : 0[1-9]
앞자리가 1인 경우 뒷자리는 0 ~ 2까지 가능 : 1[0-2]
- 일(두 자리) : (0[1-9]|[12][0-9]|3[01])
01, 02, 03, ..., 10, 11, 12, ..., 20, 21, 22, ..., 30, 31
앞자리가 0인 경우 뒷자리는 1 ~ 9까지 가능 : 0[1-9]
앞자리가 1 또는 2인 경우 뒷자리는 0 ~ 9 가능 : [12][0-9], [12]\d 둘 다 가능
앞자리가 3인 경우 뒷자리는 0 또는 1만 가능 : 3[01]
*/
regExp = /^\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])-[1-4]\d{6}$/;
if(regExp.test(value)) {
alert("정상 입력!");
} else {
alert("잘못 입력!");
}
}
</script>