통계 위젯 (화이트)

0164
862
2155407

저작권

모든 내용은 허락없이 상업적으로 사용하실 수 없습니다.
- 오광섭 -

클릭몬 (와이드)


정규표현식을 사용해보자.. ▣ 컴터야그 ▣

예전에 뉴스그룹에 올렸던 내용을 옮겨 놓습니다.. 뉴스그룹에서 의견교환시 FAQ 대용으로 활용하기 위해서..

주민등록번호, 전화번호, 우편번호, 이메일주소, IP 주소, 숫자만 입력을 받아야 하는 경우 등등 문자열을 입력받아 이를 점검해야 하는 경우가 많이 있습니다.. 뭐.. 자주 쓸 것이니 이것만 입력 받도록 해주는 에디트 컨트롤을 만드는 것도 방법이겠습니다만.. 이런 경우 저런 경우 변종에 변종.. 컴포넌트 만드는 것도 쉬운일이 아닙니다..
이제 앞으로 이런 검사들은 모두 정규표현식을 사용해 검사를 하는게 어떨까 하는 생각이 듭니다.. 아울러 검색, 치환 등에도 탁월한 편리함을 제공하죠..

이미 많은 웹 개발자들은 적극 활용을 하고 있더군요..

그도 그럴 것이 VBScript와 자바 스크립트에서는 정규표현식을 지원하는 완벽한 기능을 제공합니다.. 아주 사용하기 편리하기 때문에 별로 걱정할게 없죠..
function autolink_function(str)
    dim reg

    set reg = New RegExp
    reg.pattern =
        "(http|ftp)://([a-z0-9_-./~@?=%&:-]+)"
    reg.Global = True
    reg.IgnoreCase = True
    str = reg.Replace(str,
        "<a href='$1://$2' target=new>$1://$2</a>")

    reg.pattern =
        "([a-z0-9_-.]+)@([a-z0-9_-.]+)"
    str = reg.Replace(str,
        "<a href='mailto:$1@$2'>$1@$2</a>")

    autolink_function = str
end function
위의 코드는 HTML 문서, 혹은 문자열을 뒤벼서 http나 ftp 주소, 혹은 이메일 주소에 하이퍼링크 태그를 달아주는 함수입니다.. 파싱할 필요도 없고, 문자열 검색할 필요도 없습니다.. 치환함수에 정규표현식을 넣어주면 그 문자열 패턴에 맞는 문자열들은 알아서 지가 찾아 다 변환시켜주는 것을 볼 수 있습니다.. 정말 환상입니다..
자바 스크립트에서 정규표현식을 사용하는 방법은 아래 링크를 참조..
http://devedge.netscape.com/library/manuals/2000/javascript/1.3/guide/regexp.html

VB 스크립트 혹은 VB에서 정규표현식을 사용하는 방법은 아래 링크에..
http://www.egocube.pe.kr/asp_0003.asp

오죽하면 이런 프로그램들까지 다 나왔습니다..
http://www.vbcity.com/pubs/article.asp?alias=regexp

웹개발자들 사이에서 혹은 VB 개발자들 사이에서 정규표현식이 얼마나 많이 사용되고 있는지 잘보여주고 있습니다.. NET에서는 아래와 같은 클래스가 제공되므로 이제 .NET을 지원하는 모든 프로그래밍 언어에서 이 클래스들을 사용할 수 있게 되었습니다..
System.Text.RegularE-pressionsSystem.Web.UI.WebControls.RegularE-pressionValidator
점점 코딩하기 편해지는 세상인거 같습니다..

우왕.. 절라 편해보이는데.. C++에서는 어케 사용을 해야할까요..

안타깝게도 MFC나 C++ 표준 라이브러리에는 정규표현식을 지원하는게 없습니다.. 음.. 절라 억울합니다.. 하지만, 이 좋은 것을 알고서는 가만 앉아 있을 수만은 없습니다.. 그럼요.. 전세계에 이런 좋은 것을 알고 가만 있지 못하는 C++ 프로그래머가 최소한 몇명은 있을 것이고.. 최소 그중 한명은 웹에 자신의 클래스를 공개했을 겁니다.. 찾아봅시다..

열심히 코드그루나 코드프로젝트 사이트를 찾아보니, 이게 가장 괜찮은거 같더군요.. 하지만 아래 설명할 boost 라이브러리 가지고 삽질 하느라 테스트는 못해봤습니다.. 시간 나시는 분 함 점검 해봐주시길.. 괜찮은지 어떤지..

http://www.codeproject.com/cpp/rexsearch.asp?target=regular%7Ce-pression

나머지는 그냥 참고해볼만 합니다..
http://codeguru.earthweb.com/string/regexp.shtml
http://codeguru.earthweb.com/string/reg_ex.shtml
http://www.codeproject.com/string/cperlstring.asp?target=regular%7Ce-pression



두둥.. 언제나 진짜는 가장 마지막에 등장하는 법.. 여기 아주 막강한 boost 라이브러리의 RegEx++ 이라는 클래스가 있습니다.. boost 라는 라이브러리는 C++ 표준 라이브러리에 자신의 라이브러리를 포함시키길 희망했으나 결국 표준에 채택되지 못하자 이에 불만을 품은 프로그래머들이 차기 표준에 채택될 것을 원하며 따로 모여 만들고 있는 라이브러리인데.. 그중 RegEx++ 이라는 클래스가 정규표현식을 지원한다기에 좀 테스트를 해봤습니다..

사용해본 결과.. 음.. 정말 막강합니다.. 검색에, 치환, 유닉스의 막강한 grep 기능까지.. (사실 grep이 막강한건 정규표현식을 지원하기 때문이죠..) 정규표현식을 사용한 웬만한 문자열 조작은 다 가능하겠더군요.. 게다 많은 사람들이 개발하고 테스트에 참여해 검증도 어느정도 된 상태구요.. 성능도 높이기 위해 많은 노력을 했다고 합니다..

사용법은 다음 링크를 참조하시고..
http://www.codeproject.com/string/Regex__.asp

적용된 예는 맨 아래 소스코드를 참조하세요.. 정말 사용하기 간편하더군요.. 세팅하는게 좀 귀찮아서 그렇지.. (사실 크게 귀찮은 것도 아닙니다..) 그리고 VC++ 6에서 아주 잘 컴파일되고 동작합니다.. (흐흐.. VC++ 6이 워낙에 C++ 표준을 제대로 지원을 못한다는 악명이 높아서리.. 헐헐헐..) 다만.. 좀 아픔이 있습니다.. 무려 500K 짜리 DLL을 같이 배포를 해야 하네요..

그렇다면 저 암호와 같은 정규표현식을 어떻게 만드는 것이냐..

좋은 책이 있습니다.. 열심히 배워야죠..
정규 표현식 완전 해부와 실습(개정판)

하지만, 또 다른 방법이 있습니다.. 인터넷이 왜 좋겠습니까.. 무수한 사람들이 자신이 삽질해 만들어놓은 정규표현식을 고맙게도 이렇게 한데 다 모아두고 있습니다.. 그냥 찾아서 사용하면 됩니다.. 국내에서만 의미가 있는 우편번호, 전화번호, 주민등록번호 이런것두 있으면 좋을텐데.. 아래의 소스코드는 모두 이곳에서 가져온 정규표현식으로 테스트를 해봤습니다..

http://www.regexlib.com/Default.aspx여러분.. 문자열 검증, 검색, 치환, 삭제 등에 정규표현식을 적극 활용합시다..
#include <boost/regex.hpp>
using namespace boost ;

// 중간에 위저드가 만들어주는 코드 왕창 생략..

void CRegExTestDlg::OnButton1()
{
    boost::regex e-pression("^([a-zA-Z0-9_\-\.]+)@"
        "((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\"
        ".)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|["
        "0-9]{1,3})(\]?)$") ;

    char szTemp[1024] ;
    HWND hWnd = ::GetDlgItem(m_hWnd,IDC_EDIT1) ;
    ::GetWindowText(hWnd,szTemp,1024) ;

    CString strTemp ;
    boost::cmatch what ;
    if(boost::regex_match(szTemp, what, e-pression))
    {
        strTemp.Format("%s는 정상적인 "
            "이메일 주소 입니다.",szTemp) ;
        AfxMessageBox(strTemp) ;
        return ;
    }

    strTemp.Format("이메일 주소 잘못 넣었자녀.. "
        "니 이멜주소를 몰라? 잘 입력해봐~",szTemp) ;     AfxMessageBox(strTemp) ;
}

void CRegExTestDlg::OnButton2()
{
    boost::regex e-pression("^[-+]?\d*\.?\d*$") ;

    char szTemp[1024] ;
    HWND hWnd = ::GetDlgItem(m_hWnd,IDC_EDIT2) ;
    ::GetWindowText(hWnd,szTemp,1024) ;

    CString strTemp ;
    boost::cmatch what ;
    if(boost::regex_match(szTemp, what, e-pression))
    {
        strTemp.Format("%s는 정상적인 "
            "숫자 입니다.",szTemp) ;
        AfxMessageBox(strTemp) ;
        return ;
    }

    strTemp.Format("아.. 씨바.. "
        "숫자만 넣으라니까~ !!",szTemp) ;
    AfxMessageBox(strTemp) ;
}

void CRegExTestDlg::OnButton3()
{
    boost::regex e-pression("^(25[0-5]|2[0-4][0-9]"
        "|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])"
        "\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|"
        "[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-"
        "4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}"
        "|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}"
        "[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$") ;

    char szTemp[1024] ;
    HWND hWnd = ::GetDlgItem(m_hWnd,IDC_EDIT3) ;
    ::GetWindowText(hWnd,szTemp,1024) ;

    CString strTemp ;
    boost::cmatch what ;
    if(boost::regex_match(szTemp, what, e-pression))
    {
        strTemp.Format("%s는 정상적인 "
            "IP 주소 입니다.",szTemp) ;
        AfxMessageBox(strTemp) ;
        return ;
    }

    strTemp.Format("너 IP주소가 뭔지 모르지 ? "
        "알면 똑바로 넣어봐~ !!",szTemp) ;
    AfxMessageBox(strTemp) ;
}

아주 간단한 사용예입니다.. Boost RegEx의 막강한 문자열 기능들을 보고 싶으시면 여기를 참조하세요.. 이 글의 맨 처음 예제와 같은 비베스크립트 함수와 같은 기능을 쉽게 만들어보고 싶지 않으신가여 ?

단 몇줄로 이루어지는 문자열 검색과 점검, 정말 멋지지 않습니까 ?



핑백

  • 미친병아리가 삐약삐약 : VC++ 2008 얼마나 달라졌나.. 2008-02-02 16:23:48 #

    ... 사용할 수 있는 방법을 찾아 애용하고 있었기는 하지만, 앞으로는 boost의 regex 라이브러리를 디폴트로 사용할 수 있게 되었다.. 설마 예전 boost 처럼 regex 하나 사용했다고 별도 dll을 배포해야 하는건 아니겠지? 사이즈가 500Kb 정도니 큰 부담은 안되지만, 그래도 웬지.. 하지만, 예전의 msvcp60.dll 처럼 될 가능성도 높다.. 설마 ... more

덧글

  • 퍼그 2004/02/14 23:09 # 답글

    미친병아리님 오랫만에...^^;
    제 블로그두 방치중이라 남의 집 방문은 엄두도 못내구...
    (오늘 맛있는 초콜릿은 받으셨나요?)

    전 처음에 디자인쪽만 소질이 없나 했는데 html쪽두 영~~~
    (어렵네요. 이런걸 우찌 하시는지...)
    나중에 드림위버 배우면 괘안아 질려나...
  • 미친병아리 2004/02/15 01:48 # 답글

    네.. 오랜만이네요.. 이론, 바쁘신가봐요.. 좀 익숙해지시면 괜찮아질겁니다.. 힘 내세요~
  • 狂風 2004/02/15 13:04 # 답글

    오웃. 잘 정리 하셨네요? 전 옛날에 perl에서 처음 접했는데 그 기능에 뻑가서.. 예찬론자입니다.. 근데 정작 C/C++에서는 알고 있음에도 잘 사용안한다는 ^^;
  • 미친병아리 2004/02/15 16:25 # 답글

    狂風님 : 쿠쿠쿠.. 다른 더 좋은 방법을 찾으셨나 봅니다..
  • whohwa 2004/02/16 16:47 # 삭제 답글

    글을 읽고 나니 처음 정규식이란걸 접했을때 그 뿌듯했던 기분이 되 살아나는듯 합니다...
  • 미친병아리 2004/02/23 02:02 # 답글

    네.. 정말 감동이었습니다..
  • 오리 2007/08/22 11:17 # 삭제 답글

    VS2005에서는 CAtlRegExp Class가 있습니다.
    MSDN에서 검색하면 친절하게 예제까지 나와있습니다.
  • 미친병아리 2007/08/26 17:53 # 답글

    오리님 : .NET에서는 더 좋은 클래스가 있는가 봅니다..
  • 오리 2007/08/29 15:20 # 삭제 답글

    더 좋은 클래스는 아니고 C++에서도 간편하게 쓸수있을정도로 되어있습니다.
    C++에서 가려운곳을 긁어주는 정도라고 보시면됩니다.
  • 미친병아리 2007/09/02 12:29 # 답글

    오리님 : .NET용 클래스라고 하면 C++에서 쓰기 편하다고 하기엔 좀 그렇죠.. MC++에서 사용할 수 있는 것이라면 C++용이라고 말하긴 좀 거시기 하죠..
  • 오리 2007/09/30 19:56 # 삭제 답글

    아~부끄러버라
    윈도우에서 VS만 쓰다보니 착각을 했네요
  • 미친병아리 2007/10/03 17:12 # 답글

    오리님 : 아닙니다.. 오히려 제가 부끄럽네요.. 알고보니, CAtlRegExp 클래스는 .NET 클래스가 아니군요.. 그럼 제가 한 말이 오히려 틀린 말이고 제가 착각을 했네요.. 죄송~
댓글 입력 영역