폼처리와 정규표현식

만일 폼에서 "우편번호"를 입력받는 부분에 대해 체크루틴을 작성한다면

예는 텍스트필드 하나로 구현해보겠습니다.
<input type=text name=zip size=7 maxlength=7>

1. 녈값은 허용된다.
2. 하지만 값이 들어있을 때는 "숫자세자리-숫자세자리"거나, "수자여섯자리"
   를 꼭 지켜야 한다.
  
위의 규정을 기존에 사용되던 방식으로 체크루틴을 작성한다면

<!--  예제 ----------
var str = document.폼이름.zip
if (str.value.length != 0) {
   if (str.value.length != 6 && str.value.length != 7) {
      alert("우편번호를 다시 작성해 주세요.");
      str.focus();
      return false;
   }
   for (i = 0; i < str.value.length; i++) {
      if (!('0' <= str.value.charAt(i))&&(str.value.charAt(i) <= '9')){
      alert("우편번호를 다시 작성해 주세요.");
      str.focus();
      return false;
      }
   }
}
-->


숫자값만 체크하는것은 위의 루틴만으로 구현가능합니다.
하지만 2번의 "숫자세자리-숫자세자리"같은 조건을 위의 방법으로 구현하기에는
많은 제약이 있습니다.

뭐..  '-'문자가 1개있는지 체크하고, 나머지 6자리가 숫자인가 체크한다..
이런 방식으로 짤 수도  있겠지만,  사용자가 '11-1111'처럼 입력할 수도 있겠지요
아니면 폼을 두개로 해서 피해가는 방법도 있겠지만..
우편번호 하나 체크하는데.. 너무 코딩이 길어져도 문제가 있는 것이고요

가장 권해드리는것은 정규표현식을 사용하여 체크하는 방법입니다.
정규표현식(Regular Expressions)에 대해서는 나중에 설명드리기로 하고요,
위의 자바스크립트 코드를 정규표현식을 사용해서 고치면

<!--  예제 ----------
var str = document.폼이름.zip
if (str.value.length != 0) {
   if ((str.value.search(/\d{3}-\d{3}/) == -1) && (str.value.search(/\d{6}/) ==
 -1)) {
      alert("우편번호를 다시 작성해 주세요.");
      str.focus();
      return false;
   }
}
-->


위와 같이 단순하게 코딩할 수 있습니다.
처음의 if문은 1번조건을 체크하기 위해 넣은것이니까..
2번의 복잡한 요구를 if문 하나로 처리해 낸 것입니다.

위에서처럼.. 정규표현식을 쓰면, 쓸데없는 잔머리에 노가다를 하지 않고도
아주 간편하면서도 완벽하게 폼체크 루틴을 작성할 수 있습니다.



----------------------------------------------------------------------------
<html>
<head>
<script language=javascript>
<!--
function isload() {
   document.regular.test.focus();
}

function istest() {
   if (document.regular.test.value.search(/^aaa/) == -1) {
      alert("패턴이 일치하지 않습니다.");
      document.regular.test.focus();
   }
   else {
      alert("패턴이 일치합니다.");
      document.regular.test.focus();
   }
   return false;
  
}
-->
</script>
</head>
<body onload="javascript:isload()";>
<form name=regular onsubmit="javascript:return istest();" method=post>
<input type=text name=test size=20><br>
<input type=submit>
</form>
</body>
</html>

----------------------------------------------------------------------------

먼저 위의 /^aaa/를 간단히 해석하자면
aaa로 시작하는 모든 문자열은 참이 됩니다. aba같은경우는 거짓이 되겠지요?
그러면 위의 예에서 ^문자는 "처음"을 나타내는 것입니다.
/문자는 괄호의 역할을 하는 것이고요.

한번 실습해 보세요... 공부하는거라기보다는 재밋게 논다고 생각하세요..
정말 재밌죠?  (아닌가요?   .... 돌맞겠다.. )

^문자가 처음을 나타낸다면 "끝"을 나타내는 문자도 있습니다.
바로 $죠..

위에서 ^aaa를 tree$라는 문자열로 바꿔봅시다. search(/tree$/)이렇게 되겠죠?
그리고 웹브라우져를 리로드합시다.
그리고 위와 동일하게 pine tree라는 값을 넣어봅시다.
맞다고 나오죠?

다시 위의 변경되는 부분을 (apple|redhat|sun|ms)로 변경해 봅시다.
이번에는
sunrise
redhat linux
apple g3
ms windows
모두 일치한다고 나올 것입니다. 여기서 |는 or역할을 합니다.
apple, redhat, sun, ms들 중 하나만 일치하면 참입니다.

또 다시 [xyz]로 바꿔 봅시다.
xerox
yellow
zoo
등은 일치하며,
speaker같은 문자와는 일치하지 않을 것입니다.
[]로 둘러싸여져 있는 .. 각각의 문자 1개만 일치해도 참입니다.
자세히 말씀드리면
speaker는 x, y, z중 아무 문자도 포함하고 있지 않습니다.
그래서 거짓이 되는 것입니다.
이 연산자를 확장해서 [0-9]와 같이 쓰면 모든 숫자와 일치하며
[a-z|A-Z]이렇게 쓴다면 모든 알파벳 문자와 일치합니다. 위의 |문자와
같이 쓴 것을 주의하세요. 좀 어렵게 쓰여진 책에는 []를 문자셋이라고
표현하고 있습니다. 문자들의 집합.. 뭐 이래서 이렇게 표현한게 아닐까요?


지금까지의 예는 "특정 문자열이 존재하는가"를 파악하는 그런 단순한 예제였다면
이번 글에서 설명드릴 부분은 문자열의 포맷, 갯수등을 고려하여, 아주 세밀하게
참거짓을 판별할 수 있는 그러한 내용입니다.


다음의 표는 항목의 속성을 나타낼 때 쓰이는 기호입니다.

\b   : 단어 구분자와 일치합니다.
       (일반적으로는 space나 뉴라인문자를 나타내지만 웹브라우저에서는 문자열의
       시작과 끝과도 일치하는 것 같습니다.)
\B   : 단어구분자가 아니면 일치합니다.
\d   : 한 숫자와 일치합니다.
\D   : 숫자가 아니면 일치합니다.
\s   : 하나의 white space와 일치합니다.
       (white space : space, tab, formfeed, line feed등을 일컫는 말입니다.)
\S   : white space가 아니면 일치합니다.
\w   : 알파벳 문자와 일치합니다.
\W   : 알파벳 문자가 아니면 일치합니다.

"폼처리와 정규표현식 2"에 올려드렸던 간단한 테스트 HTML에서
정규표현식이 들어가는 부분을 ^\w+$ 라고 바꿔보시겠습니까?
위에서 \w기호는 알파벳 문자와 일치한다고 했습니다.

HTML폼에서 gom이라고 입력하시고 submit해보세요.
공백문자가 없으면 일치한다는 메시지가 나타날 것입니다.
하지만 입력폼에서 gom" 을 입력해보시겠습니까?
이번에는 백이면 백 다 일치하지 않는다는 메시지가 나타날 것입니다.

위의 표에서는 \w는 "알파벳 단어"를 의미한다고 했습니다. 더 정확히 말하면
영어 알파벳 문자와 숫자문자를 제외한 모두는 \w은 거짓으로 판단합니다.
그리고 \w뒤에 붙어 쓰이는 +문자는 수량을 나타내는 의미로 "1회 이상 반복되면 참"

의 의미를 가지고 있습니다.

그럼 위에서 쓰인 정규표현식 ^\w+$ 는 어떻게 해석되는지 살펴보기로 할까요?
\w 알파벳 단어 하나,
+는 1회이상 반복되면 참,
^는 주어진 조건으로 시작해야 한다는 의미,
$는 주어진 조건으로 끝나야 한다는 의미이니..

gom은 위의 4가지 조건을 다 만족하여 참이 되고요.
gom"은 "문자가 \w조건에서 거짓이 되므로 전체가 거짓이 됩니다.


어느정도 개념이 서는것 같습니까?
한가지만 더 테스트해 보고 .. 위에서 간단히 언급한 수량을 나타내는 기호를
공부해 보도록 합시다.

위에서 \S라는 항목이 있었죠?
설명에는 "white space가 아니면 일치합니다."라고 되어 있었습니다.
그리고 숫자를 나타내는 \d를 써 보기로 하겠습니다.
그럼 위의 예제를 응용하여 \B\d 의 정규표현식을 써봅시다.
위에서처럼 해석해 보면 "일반적인 문자, 숫자"의 조합이 있으면
참이 됩니다. 따라서 "person1, etc"라는 단어는 참을 반환할 것입니다.
"n1" 부분에서 일치하기 때문이지요.
하지만 " 1room"같은 경우에는 결코 참이 될 수 없겠지요.
공백문자는 \S에서 거짓이 되기 때문이지요.


그럼 위의 문자 속성들과 같이 사용되는 수량자들을 알아보기로 하겠습니다.

*   : 0번 혹은 그 이상 일치합니다.
+   : 1번 이상 일치합니다.
?   : 0번 혹은 1번 일치합니다.
.   : 1개의 문자와 일치합니다.
{n}   : n번 일치합니다.
{n, } : n번 이상 일치합니다.
{n, m}: n번 이상 m번 이하 일치합니다.

위에서도 말씀드렸듯이 수량자는 문자 속성 다음에 쓰여집니다.
그리고 해당 속성이 몇번 반복되는가를 나타냅니다.

예제를 보는 것이 이해하시기에는 훨씬 빠를 것입니다.
1회 연재에서 예를 들었던 우편번호를 체크하는 정규표현식을 다시 보도록 하죠.
\d{3}-\d{3} 입니다.

이제 어느정도 눈에 들어오십니까?
\d는 숫자면 참,
{3}은 3번 반복되면 참,
-는 그냥 '-'문자를 나타내고요.
따라서 "숫자3자리-숫자3자리"를 말합니다.

그리고 다른 하나 예를 들어보겠습니다.
흔히 E-mail주소를 체크하기 위해서는 무지 많은 루프를 통한 필터링을 사용해도
정확한 체크가 불가능했습니다.
하지만 \S+@\S+\.S+ 라는 표현식을 사용하면 단 한번의 조건문을 통해서 가장
정확한 형태의 E-mail주소를 체크할 수 있습니다.
KRNIC에서도 다음과 같이 정규표현식을 체크하고 있습니다. (\S+)@(\S+)\.(S+)
\w를 써도 될 듯한데.. 궂이 \S를 쓰는 이유는.. 저도 잘 모르겠고요.
다만 KRNIC에서 쓴다는 이유로 저도 최근에는 \S를 사용하고 있습니다.

----------------------------------------------------------------------------
출처              mail : 이병기 greatbk@yahoo.com
                   

댓글

이 블로그의 인기 게시물

XCOPY를 이용한 당일날짜의 파일만 카피하는방법

뽀롱 뽀롱 뽀로로 DVD 목록

SYSLOG-NG와 MySQL 을 이용한 시스로그 응용 하기