반응형

목차

1. 정규 표현식이란

2. 정규식 패턴

3. 정규식 메소드

4. 예제


1. 정규 표현식이란

 정규 표현식이란 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다.

 형식 언어를 사용하여 특정한 규칙을 가진 문자열의 패턴을 파악한다면 텍스트 편집, 포맷팅, 검색, 치환 등의 문자열 작업이 가능하게 된다. 기본적으로 패턴은 두 개의 '/(슬래시)' 사이에 작성한다. 

 

 예를 들어 '20190809'라는 문자열에서 패턴을 파악하여 '2019''08''09' 형태로 나누고, 그 사이에'-' 문자열을 삽입하여 '2019-08-09' 형태로 만들 수 있고, 저렇게 만든 날짜형 데이터에서 사용 가능한 메소드인 getDay(), getFullYear() 등을 사용할 수 있게 된다. 표현을 위한 포맷팅뿐 아니라 메소드의 사용까지도 가능하게 해주는 좋은 녀석이다.


2. 정규식 패턴

 그렇다면 이 패턴은 어떻게 만들까? 패턴을 만드는 방법은 크게 두 가지이다.

 첫째, 단순 패턴 사용

 둘째, 특수 문자 사용

 

 2.1 단순 패턴 사용

  단순 패턴은 단순히 문자열을 대응시킬 때 사용한다. 예를 들어 /hi/라는 패턴은 문자열에서 hi라는 문자열이 그대로 나타나야 대응된다. "hi, hellow"에서 hi라는 문자열이 대응된다.

 연습이 필요하다고 생각한다면 정규식을 테스트할 수 있는 사이트(https://regexr.com)를 들어가 보길 권한다. 참고로 끝에 있는 'g'는 패턴 속성으로 대상 문자열의 처음부터 끝까지 해당 패턴을 적용시키는 것이다. 이 속성이 없다면 'hi hi hi' 문자열의 대응 부분은 처음의 'hi' 하나뿐이다.

regexr.com

 

 2.2 특수 문자 사용

  단순 패턴을 사용하여 대응하기 힘든 것을 대응시키고자 할 경우 패턴에 특수 문자를 사용한다. 예를 들어, /^hi/ 패턴은 문자열의 시작이 'hi' 문자로 시작되는 것에 대응한다. 만약 'hi, hellow' 문자열에 이 패턴을 적용시킨다면 'hi'가 대응되며, 'oh, hi'라는 문자열에 적용시킨다면 대응되는 문자는 아무것도 없다.

 

특수문자의 종류와 기능이다.

특수 문자 기능 예시
^ 입력의 시작 부분과 대응된다. /^시작/ 시작했다 시작
$ 입력의 끝 부분과 대응된다.  /끝$/ → 끝났다 
* 표현식이 0회 이상 연속으로 반복되는 부분과 대응된다.

/ab*c/ → cbbabbbbcdebc, acbd

+ 표현식이 1회 이상 연속으로 반복되는 부분과 대응된다. /ab+c/ → cbbabbbbcdebc, acbd
? 표현식이 0 또는 1회 등장하는 부분과 대응된다. {0,1} 과 같다. 있어도 ok, 없어도 ok 이라고 생각하면 편하다 /010?/ 01, 010, 011
. 개행 문자를 제외한 모든 단일 문자와 대응된다. /hi./ → hi, hi1, hi2, hi12, hi 
(x) 패턴의 부분을 나누는 것. 포맷팅에 유용하게 쓰인다.

/(a)(b)/ ab

replace(/(a)(b)/,'$1-$2') → a-b

x|y | 는 or 와 동일한 기능을 하며, 하나라도 있을 시 대응된다. /fuck|suck|dick/ fuckyou, suckyou
{n} 표현식이 n번 나타나는 부분에 대응된다. /(hi){2}/ → hi, hihi, hi hi
{n,m} 표현식이 n번~m번 나오는 부분과 대응된다. /(hi){2,3}/ → hi,hihi,hihihi,hihihihi
[abc] 대괄호 안의 문자가 하나라도 있을시 대응된다. /[abc]/g a,ab,abc

https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/%EC%A0%95%EA%B7%9C%EC%8B%9D

 

정규 표현식

정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다.  이 패턴들은 RegExp의 exec 메소드와 test 메소드  ,그리고 String의  match메소드 , replace메소드 , search메소드 ,  split 메소드와 함께 쓰입니다 . 이 장에서는 자바스크립트의 정규식에 대하여 설명합니다.

developer.mozilla.org

더 많은 특수 문자에 대해 알아보고 싶다면 위의 링크로 들어가 보길 권한다.


3. 정규식 메소드

 정규식을 만들어 적용시키기 위해서는 정규식 메소드를 사용해야 한다.

 메소드 또한 위의 링크에서 잘 정리되어있기 때문에 많이 사용되는 메소드만 정리하겠다.

메소드 명 사용 방법 기능
exec pattern.exec(String) 패턴을 String에 적용하여 실행시킨다.
test pattern.test(String) 패턴을 String에 적용시킨 결과가 존재하는지 true와 false로 출력시킨다
replace String.replace(pattern,'type') 패턴을 String에 적용시키고 type으로 치환한다.

특정 문자를 제거하고 싶다면 String.replace(/\-/g, '')

 

반대로 String에 구역을 나눠 해당 구역 간격으로 '-' 문자를 넣어주고 싶다면 

 

번호에 '-' 기호 삽입

참고로 replace의 두 번째 인자인 $1, $2, $3는 정규식에서 대응되는 각각의 부분이다.


4. 예제

 입력받은 두 날짜의 시간 차이 계산하기

 

 4.1) 소스코드

  4.1.1) html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <script type="text/javascript" src="3js.js"></script>
</head>
<body>
    <input type="text" id = "date1">
    <input type="text" id = "date2">
    <input type="button" id = "dateButton" value="계산">
</body>
</html>

 

  4.1.2) Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
window.onload = function(){  
    document.getElementById("dateButton").addEventListener("click",dateCalcul);
    function dateCalcul(){
        var date1 = document.getElementById("date1").value;
        var date2 = document.getElementById("date2").value;
        var pattern = /(^(19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$/
        if(pattern.test(date1) && pattern.test(date2)){
            var formatDate1 = date1.replace(/(\d{4})(\d{2})(\d{2})/,'$1-$2-$3'); //YYYYMMDD 형태
            var formatDate2 = date2.replace(/(\d{4})(\d{2})(\d{2})/,'$1-$2-$3');
            var checkDate1 = new Date(formatDate1).getDate(); //1,2,3,4 형태, 메소드 적용 데이터
            var checkDate2 = new Date(formatDate2).getDate();
            checkDate1 = zeroFormat(checkDate1); //D 형태일때 0 추가 = DD형태
            checkDate2 = zeroFormat(checkDate2);
            var formatDate1Date = formatDate1.split('-')[2]; //DD 추출, 순수 입력 데이터
            var formatDate2Date = formatDate2.split('-')[2];
            
            if(formatDate1Date != checkDate1 || formatDate2Date != checkDate2){ //DD 형태 비교
                alert("입력한 날짜는 존재하지 않습니다");
                return;
            }
            var convertDate1 = new Date(formatDate1).getTime();
            var convertDate2 = new Date(formatDate2).getTime();
            var absDate = Math.abs(convertDate1-convertDate2);
            var result = absDate/(24*60*60*1000);
            alert(formatDate1+" 과 "+formatDate2+" 의 사이 날짜는 "+result+"일 입니다.");          
        }else{
            alert("19~20년도 사이의 정확한 날짜를 입력해주세요");
        }
    }
}
function zeroFormat(input){
    if(input<10){
        input = "0"+input;
    }
    return input;
}
 

 2번 라인 - dateButton Click 이벤트 추가 및 함수 실행

 

 4~5번 라인 - 날짜 데이터인 date1, date2의 value 값을 가져옴

 

 6번 라인 - 정규식 패턴 생성(사용자가 YYYYMMDD 형태로 입력했는지 검사)

 (^(19:20)\d{2}) - 제일 앞이 19 아니면 20, 그 뒤 숫자 2개 : 1900~2099

 (0[1-9]|1[0-2]) - '0 다음 1부터 9 사이 값' 또는 '1 다음 0부터 2 사이 값 : 01~12

 (0[1-9]|[12][0-9]|3[01])$ - '0 다음 1부터 9 사이' 또는 '1 또는 2 다음 0부터 9 사이' 또는 '3 다음 0 또는 1' : 01~31

 $ - (YYYYMMDDD와 같이 형식을 오버했을 때 검출함)

 

 7번 라인 - 입력한 두 텍스트 박스의 value에 패턴을 적용시키고 대응 여부를 확인(true or false)

 

 8~9번 라인 - Date 객체를 생성하기 위한 데이터 형식인 (YYYY-MM-DD)를 맞춰주기 위한 포매팅

 

 10-11번 라인 - 객체의 메소드를 적용하여 날짜를 가져옴

 

 12-13번 라인 - 날짜가 1일, 2일 과 같이 한 자리 수일 때 형식이 DD가 아닌 D가 됨. 즉 비교가 안되므로 DD형태로 변경해주기 위한 메소드인 zeroFormat() 호출

 

 ※ DD 형태로 변형해야 하는 이유

   사용자의 입력 날짜가 윤월일 인지 판별하기 위함 (2월 30일처럼 없을 수도 있는 날짜 판별)

   Date 객체의 getDate() 메서드는 입력한 날짜의 '일자'를 받아옴. 그런데 만약 2018년 2월 30일의 일자를 받아오면

   3일이 나오게 됨. 즉, 없는 일자만큼 카운트를 계산하여 가까운 있는 날짜에 더해줌. 2월 31일의 가장 가까운 날짜는

   3월 1일이며, 2월 28일에서 초과된 2일만큼 증가시키면 3월 3일이 나옴. = 계산 오류 발생.

   이러한 오류를 막기 위해 DD 형태로 변형하여 사용자가 입력한 날짜의 일자와 메소드를 적용시킨 일자를 비교하여

   일치할 경우 존재하는 날짜로 판별하고, 불일치할 경우 존재하지 않은 날짜로 판별하기 위함 

 

 14-15번 라인 - split 메소드를 사용하여 '-' 기준으로 나눈 배열의 3번째인 일자가 저장된 값을 읽어옴.

 

 17번 라인 - 사용자가 입력한 일자와 메소드를 적용시킨 일자를 비교

 

 21번 라인 - 입력 날짜에 문제가 없으면 해당 시간의 날짜를 시간으로 변환(milis)

 

 23번 라인 - 밀리 초로 변환된 두 날짜의 시간을 빼고 그 데이터를 절댓값으로 변환

 

 24번 라인 - 밀리초를 날짜로 변환하기 위해 각각의 단위를 곱 연산 후(1000*60*60*24 = 1일) 앞의 계산 결과와 나눔

 

4.2) 실행결과

실행결과 1
실행결과 2
실행결과 3

반응형

+ Recent posts