천객만래 [千客萬來] (It has an interminable succession of visitors)

'ASP.NET'에 해당되는 글 103건

  1. 2010.11.05 [개발] Timer 클래스 (System.Windows.Forms.Timer)
  2. 2010.11.05 [개발] 키보드상태 얻기(Ins ' Num Lock' Caps Lock)
  3. 2010.11.05 [개발] Visual C# .NET에서 프로그래밍 방식으로 전자 메일 보내기
  4. 2010.11.05 [개발] ASP.NET 파일 업로드 하기
  5. 2010.11.05 [개발] DataGrid 기본 페이저 모양 변경 방법
  6. 2010.11.05 [개발] ASP.NET 에서의 에러처리를 다루어 봅시다
  7. 2010.11.05 [개발] ASP.NET 닷넷 에디터 게시판 사용하기
  8. 2010.11.04 [개발] [asp.net]RenderControl을 이용한 엑셀로 저장
  9. 2010.11.04 [개발] Working with GridView without using Data Source Con..
  10. 2010.11.04 [개발] 파일 다운로드 구현시 한글 깨지는 문제 해결법
  11. 2010.11.01 [개발] GridView에서 DataFormatString 적용 안되는 문제..
  12. 2010.11.01 [개발] asp.net 정규식
  13. 2010.11.01 [개발] ASP.NET의 정규식
  14. 2010.11.01 [개발] C# 프로그래머 참조 - 문서 주석에 대한 권장 태그
  15. 2010.11.01 [개발] C# 프로그래머 참조 - 문서 주석에 대한 권장 태그 <c>
  16. 2010.11.01 [개발] C# 프로그래머 참조 - 문서 주석에 대한 권장 태그 <code>
  17. 2010.11.01 [개발] C# 프로그래머 참조 - 문서 주석에 대한 권장 태그 <example>
  18. 2010.10.29 [개발] C# 프로그래머 참조 - 문서 주석에 대한 권장 태그 <exception>
  19. 2010.10.29 [개발] C# 프로그래머 참조 - 문서 주석에 대한 권장 태그 <include>
  20. 2010.10.29 [개발] C# 프로그래머 참조 - 문서 주석에 대한 권장 태그 <list>
반응형

Timer 클래스
- System.Windows.Forms.Timer

 

사용자가 정의한 간격마다 이벤트를 발생시키는 타이머를 구현합니다. 이 타이머는 Windows Forms 응용 프로그램에서 사용할 수 있도록 최적화되었으며 창에서 사용해야 합니다.

 

Timer는 사용자가 정의한 간격으로 이벤트를 발생시키는 데 사용됩니다. 이 Windows 타이머는 UI 스레드를 사용하여 프로세스를 수행하는 단일 스레드 환경용입니다. 이 타이머를 사용하려면 사용자 코드에 사용 가능한 UI 메시지 펌프가 있어야 하고 항상 같은 스레드에서 수행되거나 다른 스레드로 호출을 마샬링해야 합니다.

 

이 타이머를 사용할 때에는 Tick 이벤트를 사용하여 폴링 작업을 수행하거나 지정된 시간 동안 시작 화면을 표시합니다. Enabled 속성이 true로 설정되고 Interval 속성이 0보다 크면 항상 Interval 속성 설정을 기반으로 하는 간격에 따라 Tick 이벤트가 발생합니다.

 

이 클래스는 간격을 설정하고 타이머를 시작 및 중지할 수 있는 메서드를 제공합니다.

 

생성자
- public Timer();

 

속성
- Enabled : 타이머가 실행 중인지 여부를 나타내는 값을 가져오거나 설정합니다.
- Interval  : 타이머 틱 사이의 시간(밀리초)을 가져오거나 설정합니다.

 

메소드
- Start : 타이머를 시작합니다.
- Stop  : 타이머를 중지합니다

 

이벤트
- Tick : 지정된 타이머 간격이 경과되고 타이머를 사용할 수 있을 때 발생합니다.


사용예제
: 버튼 클릭시 타이머를 중지하거나 실행시킵니다.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

 

namespace TimerTest
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button btnTime;
        private System.Windows.Forms.Timer timerNow;
        private System.Windows.Forms.Label lblTime;
        private System.ComponentModel.IContainer components;

 

        public Form1()
        {
            InitializeComponent();
        }

 

        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

 

        #region Windows Form 디자이너에서 생성한 코드
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.btnTime = new System.Windows.Forms.Button();
            this.timerNow = new System.Windows.Forms.Timer(this.components);
            this.lblTime = new System.Windows.Forms.Label();
            this.SuspendLayout();
            //
            // btnTime
            //
            this.btnTime.Location = new System.Drawing.Point(16, 48);
            this.btnTime.Name = "btnTime";
            this.btnTime.Size = new System.Drawing.Size(176, 23);
            this.btnTime.TabIndex = 1;
            this.btnTime.Text = "타이머 중지";
            this.btnTime.Click += new System.EventHandler(this.btnTime_Click);
            //
            // timerNow
            //

            this.timerNow.Interval = 1000;
            this.timerNow.Tick += new System.EventHandler(this.timerNow_Tick);
            //
            // lblTime
            //

            this.lblTime.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblTime.Font = new System.Drawing.Font("굴림", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(129)));
            this.lblTime.Location = new System.Drawing.Point(16, 16);
            this.lblTime.Name = "lblTime";
            this.lblTime.Size = new System.Drawing.Size(176, 23);
            this.lblTime.TabIndex = 2;
            this.lblTime.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            //
            // Form1
            //

            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
            this.ClientSize = new System.Drawing.Size(208, 85);
            this.Controls.Add(this.lblTime);
            this.Controls.Add(this.btnTime);
            this.Name = "Form1";
            this.Text = "Timer테스트";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);

        }
        #endregion

 

        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

 

        //카운트 다운 숫자 표시 변수 선언
        private int countdown = 0;

 

        //Timer.Enabled이 true가 되면 Timer.Interval에서 지정해준 밀리초마다 아래 메소드 실행.

        private void timerNow_Tick(object sender, System.EventArgs e)
        {
            //지정해준 밀리초마다 라벨에 카운트 다운숫자값을 넣어줍니다.
            this.lblTime.Text = "카운트다운 : " + (countdown++);
        }

 

        //Timer가 시작된 상태에서 버튼을 클릭하면 타이머를 중지하고
        //Timer가 중지된 상태에서 버튼을 클릭하면 타이머를 계속 실행하는 메소드

        private void btnTime_Click(object sender, System.EventArgs e)
        {
            if(this.timerNow.Enabled)
            {
                //this.timerNow.Enabled = false;
                this.timerNow.Stop();
                this.btnTime.Text = "타이머 시작";
            }
            else
            {
                //this.timerNow.Enabled = true;
                this.timerNow.Start();
                this.btnTime.Text = "타이머 중지";
            }
        }

 

        //폼이 로드될때 타이머를 실행시킵니다.
        private void Form1_Load(object sender, System.EventArgs e)
        {
            //this.timerNow.Enabled = true;
            this.timerNow.Start();

        }
    }
}

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


 http://blog.naver.com/tear230/100003039681

 

지금 키보드입력이 삽입상태인지 수정상태인지, Caps Lock이 켜져 있는지 꺼져있는지를

GetKeyState API를 이용 알아내는 방법입니다.

 

MFC가 그랬듯이 .NET Library가 Windows API를 완전히 표현하고 있지는 않는 것 같습니다.
그러나 C#에서 Unmanaged Code를 사용할 수 있으니까 Windows API를 직접 사용하면 되겠지요.    


 

using System.Runtime.InteropServices;
...

[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);


[DllImport("User32.dll")]
public static extern short GetKeyState(int nVirtualKey);

private void textBox1_TextChanged(object sender, System.EventArgs e)
{
     if ((GetKeyState(0x15) & 0x01) == 0x01) MessageBox(0, "Hangul Key", "Sunken", 0);
     if ((GetKeyState(0x14) & 0x01) == 0x01) MessageBox(0, "CapsLock Key", "Sunken", 0);
     if ((GetKeyState(0x90) & 0x01) == 0x01) MessageBox(0, "NumLock Key", "Sunken", 0);

자료출처 : http://www.devpia.com/

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


 http://blog.naver.com/tear230/100002712722

HOWTO: System.Web.Mail 및
Visual C# .NET에서 프로그래밍 방식으로 전자 메일 보내기

 

요약

이 문서에서는 System.Web.Mail을 사용하여 Visual C#. NET에서 전자 메일 메시지를 보내는 방법을 설명합니다.

 

추가 정보

1. Microsoft Visual Studio .NET을 시작합니다. 파일 메뉴에서 새로 만들기를 누른 다음 프로젝트 누릅니다. Visual C# 프로젝트를 누르고 콘솔 응용 프로그램 템플릿을 누른 다음 확인을 누릅니다. 기본적으로 Class1.cs가 만들어집니다.

 

2. System.Web.dll에 대한 참조를 추가합니다. 다음과 같이 합니다.
   - 프로젝트 메뉴에서 참조 추가를 누릅니다.
   - .NET 탭에서 System.Web.dll을 찾아 선택 누릅니다.
   - 참조 추가 대화 상자에서 확인을 눌러 선택한 내용을 적용합니다. 
     선택한 라이브러리에 대해 래퍼를 생성할 것인지 묻는 메시지가 표시되면 예를 누릅니다.

 

3. 코드 창에서 전체 코드를 아래의 코드로 대체합니다.

 

using System;
using System.Web.Mail;

namespace WebMail
{
    class Class1
    {
        static void Main(string[] args)
        {
            try
            {
                MailMessage oMsg = new MailMessage(); 
               
// TODO: Replace with sender e-mail address.
                oMsg.From =
sender@somewhere.com;

                // TODO: Replace with recipient e-mail address.
                oMsg.To =
recipient@somewhere.com;
                oMsg.Subject = "Send Using Web Mail";   
          
               
// SEND IN HTML FORMAT (comment this line to send plain text).
                oMsg.BodyFormat = MailFormat.Html;
               
               
// HTML Body (remove HTML tags for plain text).
                oMsg.Body = "<HTML><BODY><B>Hello World!</B></BODY></HTML>";
               
              
  // ADD AN ATTACHMENT.
                // TODO: Replace with path to attachment.
                String sFile = @"C:\temp\Hello.txt"; 
                MailAttachment oAttch = new MailAttachment(sFile, MailEncoding.Base64);
 
                oMsg.Attachments.Add(oAttch);

                // TODO: Replace with the name of your remote SMTP server.
                SmtpMail.SmtpServer = "MySMTPServer";
                SmtpMail.Send(oMsg);

                oMsg = null;
                oAttch = null;
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} Exception caught.", e);
            }
        }
    }
}

4. "TODO"가 나타나는 코드를 수정합니다.
5. F5 키를 눌러 프로그램을 빌드하고 실행합니다.
6. 전자 메일 메시지를 보내고 받았는지 확인합니다.

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


 http://blog.naver.com/duraboys/130014400093

기존 ASP에서 클라이언트 컴퓨터에서 서버로 파일을 업로드하기 위해서는 개발자가 업로드에 관련된 컴포넌트를 직접 만들던가 타사 제품의 COM 컴포넌트(써드파티 컴포넌트)를 이용하여야 하였다. 가장 손쉬운 방법은 SA-FileUp이나 ASPUpload 같은 써드파티 컴포넌트를 사용하는 것이다. 이 컴포넌트를 보통 regsvr32.exe란 툴을 사용해서 등록한후에 ASP에서 사용할 수 있었다. 이를 하기 위해서는 로컬로서 접속하여야 하고 이 컴포넌트를 업데이트하거나 제거하기 위해서는 웹서버가 정지하여야 하였다. 또한 타사 제품이기 때문에 돈이 든다.

ASP.NET에서는 다른 COM 컴포넌트 필요없이 업로드를 할 수 있는 기능을 제공한다. 이는 닷넷 프레임웍의 HtmlInputFile 클래스를 통해서 구현된다. 이 클래스의 인스턴스를 생성하고나면 몇줄의 코드로서 업로드 기능을 구현할 수 있다. 이제 파일의 업로드에 대해서 알아보자. 또한 업로드 폴더 생성같은 부가적인 기능도 추가해보겠다.

파일경로 입력

파일을 업로드하기 위해서는 서버사이드 폼을 사용하여야 한다. 중요한점은 폼에 ENCTYPE="Multipart/Form-Data" 속성이 명시되어야 한다. 다음으로 input 컨트롤을 추가하자.

<input type="file" id="ID" runat="server" />

runat="server"는 매우 중요하다. 이 컨트롤은 단순한 텍스트박스처럼 보인다. 하지만 runat="server"로 인하여 서버컨트롤로 인식된다. Browse버튼을 누르면 로컬 컴퓨터의 파일을 선택할 수 있는 상자가 나타난다.

Form에 encType을 꼭 넣어주도록 하자. 그리고 HtmlInputFile 컨트롤과 그 아래에 버튼컨트롤과 파일의 이름등의 정보를 보여주는 레이블 컨트롤을 추가하였다. HtmlInputFile 컨트롤의 형식은 다음과 같다.

<Input
          Type="File"
          RunAt="Server"
          ID="고유하게할 아이디"
          Accept="MIME 인코딩"
          MaxLength="파일의 최대크기 설정"
          Size="파일경로를 입력받을 텍스트박스의 길이" >

이제 코드부분을 보도록 하자.

System.IO 네임스페이스를 추가하자.

업데이트할 디렉터리로 D:\Test로 지정하였다. 이 디렉터리가 있는지 또는 생성을 위해서 DirectoryInfo 클래스가 필요하다. 이때문에 System.IO 네임스페이스를 추가한 것이다. 폴더가 존재하지 않는다면 이 폴더를 생성하고 레이블에 생성하였다는 메시지를 출력한다.

이것은 Upload버튼을 눌렀을때의 이벤트 핸들러이다. 각각의 레이블에 해당하는 정보를 출력하도록 하고 GetFileName 메서드를 사용하여 파일 이름을 가져온다. 그리고 SaveAs 메서드를 사용하여 지정한 디렉터리에 가져온 파일이름으로 저장한다.

디렉터리가 존재하지 않을때 실행시킨 화면이다. 디렉터리가 생성되었다.

찾아보기 버튼을 누르면 로컬 컴퓨터의 파일을 선택할 수 있다.

선택하고 Upload버튼을 눌렀을때의 화면이다.

실제 폴더에 파일이 업로드 되었다.

제공 : 코리아인터넷닷컴, a 2002년 06월 28일
저자 : Tribikram Rath

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


출처 : HOONS 닷넷

원문 : http://www.hoonsbara.com/hoonsboard.aspx?table_name=asptip&board_idx=445396&page=9&keyword=&search=&boardmode=2

 

웹프로그래밍의 기초인 게시판을 작성할 때 ASP.NET 1.x의 DataGrid를 많이

사용하는데 편리하고 상용 그리드에 비해 가볍지만 기능이 부족한 점(셀 머징, 소팅, 스크롤)이

있습니다.

개인적으로 불만이었던 점 중의 하나가

게시판의 페이지 번호 부분이었는데

DataGrid 컨트롤이

'... 1 2 3 4 5 ...'과 같이 일반적인 게시판에 있는

'[처음][이전]1 2 3 4 5 [다음][마지막]'과

같은 모습을 제공해 주지 않고 있습니다.

이 부분을 커스터마이징 할 수 있는 방법은

DataGrid 컨트롤의 ItemCreated란 이벤트 핸들어에 아래 코드를 추가하면 됩니다.

게시판의 페이저 부분을 '◀ 1 2 [3] 4 5 ▶'로 바꿔줍니다.

 

            bool exist = false;

            if(e.Item.ItemType == ListItemType.Pager)

            {

                 TableCell Pager = (TableCell)e.Item.Controls[0];

                Pager.VerticalAlign = VerticalAlign.Middle;

                for(int n=0; n<Pager.Controls.Count; n+=2)

                {

                    try

                    {

                        Label l = (Label) Pager.Controls[n];

                        l.Text = "["+l.Text+"]";

                        l.CssClass = "plinkstyle";

                    }

                    catch

                    {

                        LinkButton h = (LinkButton) Pager.Controls[n];

                        if((h.Text == "...") && (!exist))

                        {

                            h.Text = "◀";

                            h.CssClass = "plinkstyle";

                        }

                        else if((h.Text == "...") && (exist))

                        {

                            h.Text = "▶";

                            h.CssClass = "plinkstyle";

                        }

                        else

                        {

                            exist = true;

                            h.CssClass = "plinkstyle";

                        }

                    }

                }

            }

 

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


출처 : HOONs 닷넷

원문 : http://www.hoonsbara.com/hoonsboard.aspx?table_name=asptip&board_idx=445268&page=10&keyword=&search=&boardmode=2

 

ASP.NET 에서의 에러처리를 다루어 봅시다.

에러처리

web.config를 이용한 에러처리
기본적으로 에러가 발생했을 경우 redirect 페이지를 설정합니다.
400,500번대의 에러를 statecode로 정의 할 수 있습니다.

[ 소스코드]

"RemoteOnly" defaultRedirect="Error.aspx">
    "404" redirect="not_found.aspx" />


statusCode가 정의 되어있으면 정의된 곳으로 아니면 기본적으로 defaultRedirect를 향합니다.

 

global.asax 에서의 에러처리
에러가 발생했을때의 페이지 이동은 간단히 web.config를 이용하면 됩니다.하지만
좀더 자세하게 에러 내용을 보고 싶다던지 그에 관한 상세적인 내용을 다루기 위해서는
global.asax를 이용하면 편리합니다.

[ Application_Error]

protected void Application_Error(Object sender, EventArgs e)
{
   Exception LastError = Server.GetLastError();
   string errMsg = LastError.ToString();
   string errSource = "source : "+LastError.Source;
   string errTrack = "
track : "
+LastError.StackTrace; string errMsg = "
Message : "
+LastError.Message; string errTarget = "
Target : "
+LastError.TargetSite; string logName = "ddarangLog"; string Message = "URL :" + Request.Path + "
Error : "
+ errMsg; //윈도우즈 이벤트로그에 작성하기
    if(!EventLog.Exists(logName))
   {
       EventLog.CreateEventSource(logName,logName);
   }
   EventLog Log = new EventLog();
   Log.Source = logName;
   Log.WriteEntry(Message, EventLogEntryType.Information, 1);
   Log.WriteEntry(Message, EventLogEntryType.Error, 2);
   Log.WriteEntry(Message, EventLogEntryType.Warning, 3);
   Log.WriteEntry(Message, EventLogEntryType.SuccessAudit, 4);     
   Log.WriteEntry(Message, EventLogEntryType.FailureAudit, 5);

   //운영자에게 에러메일발송  ddarangUtil.SendMail("에러발생",Message,"1",Mailip);

}

 

trace에 관하여
trace를 활성하하면 응용 프로그램 내의 모든 페이제에 대한 추적 로그 출력이 가능합니다.
페이지 단위로 할 수도 있구 전체 프로젝트에 적용시킬 수도 있습니다.

페이지 단위는 페이지 지시자에 trace="true"를 추가시킵니다.
모든 페이지 단위는 web.config를 이용합니다.

[ 소스코드]


    "false"
        requestLimit="10"
        pageOutput="true"
        traceMode="SortByTime"
        localOnly="false"
    />

enabled 항목을 "true"로 설정하면 루트디렉토리에 trace.axd 파일이 생성됩니다.
이 파일은 xml로 구성이 되어져 있어서 브라우져에서 바로 확인이 가능합니다.

ex) http://localhost/ddarant/trace.axd
 

 

 

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요



출처 : HOONS 넷

[ASP.NET Controls]
[HOONS] 닷넷 에디터 게시판 사용하기


  강좌 최초 작성일 : 2004년 3월 24일
  강좌 최종 수정일 : 2004년 3월 24일 

  작성자 : HOONS(박경훈)
http://www.hoonsbara.com

  강좌 제목 : 닷넷 에디터 게시판을 사용하자!! 
 



강좌 제목을 쓰고 보니깐 상당히 어색한 기분이 든다-_-;; 에디터 게시판.. 이건 무엇인가? 음;; 태그 초보자를 위한 에디터 텍스트 박스라 정의를 내린다면 이해할려나..(아하?ㅇㅋㅇㅋ??) 필자가 예전에 한참 공부 하던 시절 이 에디터 텍스트 박스를 만들어 보겠다고 일주일 동안 혼신을 투자해 고생한 경험이 있었다. 결론은 버그 투성이의 에디터 텍스트 박스를 만들어 낸것이 고작-_-;; 느낌인점이 있다면 개발자들이 에디터 게시판을 괜히 상용화 하여 판매하는게 아니다라는 걸 느끼게 되었다.

"자~ 이제 그럼 어떤 에디터 게시판을 사서 사용 하는것이 현명한 판단 일까? "

이렇게 말을 하고 여기저기 에디터 텍스트 박스를 소개시켜 준다면 한순간 광고업자로 오인 받아 창을 닫아 버리지 않을까 싶다-_-;; 
"그럼 만들기도 힘들고 사자니 돈들고 그럼 어떻게 하라는 건가?"
이런 불만의 마인드를 혹시 품어 본적은 없었는지 (서론이 길면 주책이라던데-_-;) 
자 결론은 이제 FreeTextBox라는 에디터 텍스트 박스를 사용하면 된다는 것이다._-_;;  이것은 어느 오픈소스를 구해서 한국판에 맞추어서 리컴파일 시킨 것이고(수정도 굉장히 어려웠다는_-_;;) 오바되는 기능들을 줄여서 나름대로 가볍게 만들어 본것이다.


[그림 FreeTextBox]

자 이러한 텍스트 박스를 이제 사용해 보도록 하겠다. 이것은 닷넷 사용자 지정 컨트롤로 컴파일이 되어 있기 때문에 사용방법은 정말로 간단하다.


1.다운로드

-이미지와스타일 다운로드:
 



-DLL,ftp.inserttable.aspx 다운로드:



2.사용하기

자, 이제 정말 쉬운 에디트 텍스트 박스를 한번 사용해 보도록 하겠다.
먼저 ASP.NET프로젝트를 만들어 보도록 하자. 필자는 Test1s라는 프로젝트를 만들었다. 다운받은 Textimg라는 파일을 압축을 풀어서 이 프로젝트 폴더에 안에 넣어 두도록 하자. 그로고 다운 받은 DLL 역시 압축을 푼후에 Bin이라는 폴더 안에 배치 시킨다.

[프로젝트폴더]-[bin]-HoonstextBox.dll
                     -[TextImg]-여러가지 이미지들과 스타일
                     -ftp.inserttable.aspx

이렇게 배치가 되었으면 이제 아래와 그림을 따라서 DLL 항목을 가져와 보도록 하자.
도구상자에서 오른쪽 마우스를 눌러보자 그러면 항목 추가/제거 라는 메뉴가 나타 날것이다.





항목 추가/삭제 목록을 열어 보면 아래와 같은 창이 뜬다 여기서 찾아보기 버튼을 누른다.




그러면 아까 전에 준비 했었던 bin 이라는 폴더에 HoonsTextBox.dll이라는 파일을 선택하자.



선택을 하면 아래와 같이 항목에 추가가 되는것을 볼수 있을 것이다. 이제 확인 버튼을 누르고
창을 나와 보자.




이제 FreetextBox라는 항목이 생긴 것이다.(이런것을 사용자 지정 컨트롤이라고 이야기한다.)
그러면 한번 텍스트 박스를 끌어오는 놓는 것처럼 똑같이 이 컨트롤들 가져다가 페이지에 넣어보도록
하자.




그럼 아래와 같은 컨트롤이 표시가 된다. 이제 이 컨트롤들의 속성에 이미지와 스타일을
셋팅해주게 되면 되는것이다.



이텍스트 박스의 속성을 경로 부분이 있다. 아래와 같이 이미지와 스타일의 경로를 적어주자..
그리고 ToolbarType에 따라서 보드 툴색이 변하게 된다는 것을 잊지 말자.

 

자 , 이제 실행을 시켜 보면 에디터 게시판이 완성된 것을 볼수 있을것이다.
음;; (ID)라는 부분의 속성을 이용해서 ID값을 편집할수 있고, 안의 내용도 Text라는 속성으로 접근한다.
기존의 텍스트 박스와 유사하기 때문에 이용하는데 특별히 불편한 사항은 없을것이다.

강좌라기 보다는 팁이 된듯-_-;; 다음에는 팁이 아닌 강좌로 다시 찾아 볼것을 기약하며 그럼~

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


기본적인 페이지 로드시 웹페이지가 아닌 엑셀시트임을 표시하는 것 만으로도

엑셀페이지 표시가 가능하다. 익스플로러를 이용해서 그런갑다...

 

        private void Page_Load(object sender, System.EventArgs e)

        {

            Response.ContentType = "application/vnd.ms-excel";

            Response.ContentEncoding = System.Text.UTF7Encoding.UTF7;

            string strReturn = "";

        }

 

2. DataGrid의 RenderControl를 이용해 엑셀로 저장하는 메서드를 보자..

데이터 그리드 내용만 저장된다.. 신기하죵?

 

        private void ImageButton1_Click(object sender, System.Web.UI.ImageClickEventArgs e)

        {

            string fileName = DateTime.Now.ToString("yyyyMMddHHmmss")+".xls";

            Response.ContentType = "application/vnd.ms-excel";

            Response.AddHeader("Content-Disposition","attachment;fileName="+fileName);

            Response.Charset = "";

            DataGrid1.EnableViewState = false;

            System.IO.StringWriter tw = new System.IO.StringWriter();

            tw.WriteLine("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=euc-kr\">");//한글 깨짐 방지

            System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);

            DataGrid1.RenderControl(hw);

            Response.Write(tw.ToString());

            Response.End();

        }

 

3. 응용해서 어떠한 개체의 RenderControl를 이용해 엑셀로 저장 가능하다.

  일반 테이블로 만든 것에도 단순히... runat=server와 id를 부여하여 저장 가능하다.

  그라몬 서버 컨트롤로 인식 해부니까...

 다음의 예는 일반 테이블 테그에 서버컨트롤 지정해서 저장한다. 위에 데이터 그리드랑 별 차이 없다.

 

        private void btnExcel_Click(object sender, System.EventArgs e)

        {

            string fileName = "aa_"+DateTime.Now.ToString("yyyyMMddHHmmss")+".xls";

            Response.ContentType = "application/vnd.ms-excel";

            Response.AddHeader("Content-Disposition","attachment;fileName="+fileName);

            Response.Charset = "";

            System.IO.StringWriter tw = new System.IO.StringWriter();

            tw.WriteLine("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=euc-kr\">");//한글 깨짐 방지

 

            // 그래프도 함께 나도오록 하자..

            Chart1.HtmlTag = "Jpeg";

            Chart1.ImgWidth = 1000;

            tw.WriteLine(Chart1.GetHtmlTag(1000,450).Replace("IMG SRC=\"","IMG SRC=\"http://www.aaa.com")+"<br>");//그림을 붙이자.. 쩝쩝..

 

            System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);

            this.tabResultList.RenderControl(hw);

            Response.Write(tw.ToString());

            Response.End();

        }


출처: http://www.devpia.com/blog/myblog.aspx?pdsidx=2304&ownerid=surfex

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


Introduction

There are many articles and tutorials around that illustrate the use of GridView control along with the new Data Source Controls. When attached with a Data Source control GridView performs tasks such as paging, sorting and editing automatically i.e. without writing any code. However, at times you require to bind the GridView with a DataView or DataTable directly. Fortunately GridView can also be used without attaching with the Data Source Controls. This calls for some extra coding from developer's end. If you are familiar with DataGrid control of ASP.NET 1.x then you will find the coding similar. In this article we will see how paging, sorting and editing can be implemented in a GridView control that is bound with a DataView (or DataTable) directly.

Example - Employee listing

As an example we are going to use Employees table of the Northwind database. In order to develop a test web form create a new web site in VS.NET 2005. Drag and drop a GridView control on the web form. Add three BoundFields and a CommandField to the GridView with the help of Fields dialog (see below).

Set various properties of the BoundFields as shown in the following table:

BoundField HeaderText DataField ReadOnly
Employee ID Employee ID EmployeeID true
First Name First Name FirstName false
Last Name Last Name LastName false

Go in the code behind of the web form and add the following code in the Page_Load event:

protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
BindGrid();
}
}

Here, we call BindGrid() method if the web form is being served as a result of first request. The BindGrid() method is our own function that we will create later on. The method essentially binds the GridView with a DataView. The DataView supplies all the records from the Employees table.

Implementing Paging

In order to implement paging you need to set AllowPaging property of the GridView control to True. Then set PageSize property to 3. There are two events of GridView that are related to paging. They are:

  • PageIndexChanging
  • PageIndexChanged

The former event is raised before the current page changes and the later is raised after the page has changed. The former allows you to cancel the operation.

Write the following code in the PageIndexChanging event of the GridView.

protected void GridView1_PageIndexChanging
(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
BindGrid();
}

The PageIndexChanging event handler receives an event argument of type GridViewPageEventArgs. This argument provides the new page number that the user has selected via a property called NewPageIndex. We set PageIndex property of the GridView to this new page number and call the BindGrid() method again. This will display the corresponding records in the GridView. The following figure shows the GridView after implementing paging.

Implement Sorting

Implementing sorting requires a bit of more work. First of all, you need to set AllowSorting property of the GridView to True. Further, you need to set SortExpression property of the BoundFields to the name of the column on which you would like to sort the grid. Once you set these properties you will find that the column headers of all the columns for  which you specified SortExpression property appear as clickable link buttons. Clicking on the link buttons raise two events:

  • Sorting
  • Sorted

Just like paging events these events follow pre and post pattern. The Sorting event allows you to cancel the operation also.

The Sorting event handler receives an event argument of type GridViewSortEventArgs. The GridViewSortEventArgs class has three important properties. The SortExpression property supplies the sort expression that you specified earlier for the column being sorted. The SortDirection property specifies the direction of sorting i.e. ascending or descending. This property is not of much when you are sorting the grid on your own. However, when coupled with data source controls the GridView can toggle the sorting direction automatically for you and you can get/set the direction using this property. The Cancel property allows you to cancel the sorting operation.

Since we are not using data source controls we need to handle the toggling of the sort direction on our own. We do this by storing a ViewState variable. Add the following code in the Sorting event handler.

protected void GridView1_Sorting(object sender, 
GridViewSortEventArgs e)
{
ViewState["sortexpression"] = e.SortExpression;

if (ViewState["sortdirection"] == null)
{
ViewState["sortdirection"] = "asc";
}
else
{
if (ViewState["sortdirection"].ToString() == "asc")
{
ViewState["sortdirection"] = "desc";
}
else
{
ViewState["sortdirection"] = "asc";
}
}
BindGrid();
}

Here, we store the value of SortExpression property into a VeiwState variable called sortexpression. We need to access this variable from BindGrid() method so that our sorting will work correctly under all the circumstances. Similarly we set a ViewState variable called sortdirection. This variable stores the direction of sorting i.e. asc or desc. Note how we are toggling the direction. Finally, we call BindGrid() method which will bind sorted version of the DataView with the grid.

The following figure shows the GridView after implementing sorting.

Implement Editing

In order to edit records displayed in the GridView, we need to add a CommandField to the GridView. By default this field renders a link button titled Edit. Once we click on edit the GridView raises an event called RowEditing and the Edit link button changes to Update and Cancel link buttons. Clicking on Update link button raises RowUpdating event whereas clicking on the Cancel link button raises RowCancelingEdit event. We need to write our own code to update the new values back to the database in the RowUpdating event.

Add the following code in the RowEditing event handler:

protected void GridView1_RowEditing
(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
BindGrid();
}

The RowEditing event handler receives an event argument of type GridViewEditEventArgs. The GridViewEditEventArgs class has a property called NewEditIndex that tells us the row number being edited. We need to set the EditIndex property of the GridView to this new edit index. This will cause the GridView to enter in edit mode (see below).

Note that the EmployeeID column is not editable because we have marked it as ReadOnly.

Now add the following code in the RowCancelingEdit event handler.

protected void GridView1_RowCancelingEdit
(object sender, GridViewCancelEditEventArgs e)
{
GridView1.EditIndex = -1;
BindGrid();
}

Here, we set the EditIndex property of GridView to -1 indicating that we intend to cancel the edit operation.

Finally, we will write code for handling the RowUpdating event.

protected void GridView1_RowUpdating
(object sender, GridViewUpdateEventArgs e)
{
int empid;
string fname, lname;
empid = int.Parse(GridView1.Rows[e.RowIndex].
Cells[0].Text);
fname = ((TextBox)GridView1.Rows[e.RowIndex].
Cells[1].Controls[0]).Text;
lname = ((TextBox)GridView1.Rows[e.RowIndex].
Cells[2].Controls[0]).Text;

SqlConnection cnn = new SqlConnection(@"data source=
.\sqlexpress;initial catalog=northwind;integrated 
security=true");
cnn.Open();
SqlCommand cmd = new SqlCommand("update employees set 
firstname=@fname,lastname=@lname where employeeid=@empid",
 cnn);
cmd.Parameters.Add(new SqlParameter("@fname",fname));
cmd.Parameters.Add(new SqlParameter("@lname", lname));
cmd.Parameters.Add(new SqlParameter("@empid", empid));
cmd.ExecuteNonQuery();
cnn.Close();

GridView1.EditIndex = -1;
BindGrid();
}

Here, we first retrieve the new values entered in the textboxes. The RowUpdating event handler receives an event argument of type GridViewUpdateEventArgs. The GridViewUpdateEventArgs class has a property called RowIndex that tells us the row number being updated. We retrieve the new values using the Rows collection of the GridView. Note how the Cells and Controls collections are used. The Cells collection contains all the columns of the current row whereas Controls collection contains all the controls from a specific column. The Controls collection stores all the controls as generic Control type. Hence we need to type cast the controls to TextBox class. Then we create a connection, command and parameters and execute an UPDATE query against the database. Once the updating operation is over we set EditIndex property of the GridView to -1 and bind the grid again.

The BindGrid() method

Throughout our code we have used a method called BindGrid(). It's time to unveil the BindGrid() method now.

private void BindGrid()
{
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter
("select * from employees", @"data source=
.\sqlexpress;initial catalog=northwind;
integrated security=true");
da.Fill(ds,"employees");
DataView dv = ds.Tables[0].DefaultView;

if (ViewState["sortexpression"] != null)
{
dv.Sort = ViewState["sortexpression"].ToString() 
+ " " + ViewState["sortdirection"].ToString();
}

GridView1.DataSource=dv;
GridView1.DataBind();
}

Here, we fill a DataSet with all the records from Employees table. Then we create a DataView based on the employees DataTable. Then we sort the DataView using the Sort property. The column on which we wish to sort the DataView is obtained from the  sortexpression ViewState variable. While sorting we also make use of sortdirection ViewState variable. Recollect that we set these two ViewState variables in the Sorting event handler. Finally, we set the DataSource property of the GridView to the DataView and then call its DataBind() method.

Summary

GridView can be bound with a DataView (or DataTable) directly without using data source controls. We can implement the same paging, sorting and editing features. However, we need to handle various events ourselves and do some extra work so that all the features work as expected.

 
 
Related Articles
Persistant and Bidirectional Sorting In DataGrid
Downloadable DataGrid samples for beginners
Downloadable DataList samples for beginners
Creating DataGrid Programmatically
Building a Master/Detail DataGrid for Database Inserts
Recalculating Column Values in DataGrid
HOW TO: Display DataGrid in small screen area without using Paging
Creating DataGrid Templated Columns Dynamically - Part I
Creating DataGrid Templated Columns Dynamically - Part II
Displaying Two DataTables In One DatGrid
Displaying Images from SQL Server database in DataGrid
Display Conditional Data In DataGrid Column
Confirming Deletes in ASP.NET DataGrid
Adding Paging Functionality To DataList
Alphabetical Paging in DataGrid
Quickly Adding A New Row In DataGrid
Custom Paging In DataGrid
Sorting Template Columns of ASP.NET DataGrid
Using Radio Buttons To Select DataGrid Row
Creating Master-Detail Listings using ASP.NET controls
Creating GridView Columns Dynamically (Part 1)

Creating GridView Columns Dynamically (Part 2)



출처: http://www.dotnetbips.com/default.aspx

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요



이번 내용은 팁이라고 하기에는 좀 그렇고 제가 한참 고생하다 방법을 찾아서 너무 기쁜 나머지 여기에 올리게 되었습니다. ^^;;

대단한건 아니고 닷넷에서 파일 다운로드 구현할때 파일명에 한글이 있으면 다운로드 창에서 파일명이 깨져서 나오는 현상 해결 방법 입니다.

일단 소스를 보시면 다들 이해 하시리라 생각됩니다.



public static void FileDownload(string sFileName)
{
try
{
//파일 저장 경로
string sBoardDataPath = ConfigUtil.GetUploadRootPath() + "\\NB_BoardData_001001";

string sTmpFilePath = sBoardDataPath.Trim() + "\\" + sFileName.Trim();

//헤더에 파일 이름 지정
Response.ClearHeaders();
Response.ClearContent();

Response.ContentType = "multipart/form-data";
Response.AddHeader
("Content-Disposition", "attachment;filename=" + Server.UrlPathEncode(sFileName));
Response.WriteFile (sTmpFilePath);
Response.Flush();
Response.Close();
}
catch(Exception E)
{
throw E;
}
}






위 소스는 내보드에서 사용하는 파일 다운로드 함수를 약간 수정한 것 입니다.


위 소스에서 UrlPathEncode 이 부분이 한글 파일명을 안깨지고 보여지도록 하는 부분 입니다.


어딜 찾아보니 UrlEncode로 하면 된다고 하던데 안되더군요.

UrlEncode과 UrlPathEncode에 대한 자세한 설명은 다음 MSDN 페이지를 참조하시면 됩니다.

UrlEncode 설명
UrlPathEncode 설명

벌써 다들 알고있는 내용이었다면 대략낭패 ;;
반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


GridView에서 DataFormatString 을 적용했는데... 반영이 안되는 문제가 발생한다.
이런 경우 HtmlEncode 의 속성값(default: true)을 False로 해주면 해결된다. 

예를 들면...


<간단하게 GridView로 데이터를 표시... DataFormatString 적용전 화면>



<DataFormatString 적용 후 화면>

두 그림을 보면 달라진 점은 ModifiedDate 필드에 날짜 형식이 바뀐것을 확인 할 수 있다.

DateTime type인 ModifiedDate에 DataFormatString을 적용했다.
아래 소스 10줄에 굵은 부분을 확인...
 

    1 <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="AddressID" DataSourceID="SqlDataSource1" AllowPaging="True" AllowSorting="True" BackColor="#DEBA84" BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px" CellPadding="3" CellSpacing="2" PageSize="5">

    2   <Columns>

    3      <asp:BoundField DataField="AddressID" HeaderText="AddressID" InsertVisible="False" ReadOnly="True" SortExpression="AddressID" />

    4      <asp:BoundField DataField="AddressLine1" HeaderText="AddressLine1" SortExpression="AddressLine1" />

    5      <asp:BoundField DataField="AddressLine2" HeaderText="AddressLine2" SortExpression="AddressLine2" />

    6      <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />

    7      <asp:BoundField DataField="StateProvinceID" HeaderText="StateProvinceID" SortExpression="StateProvinceID" />

    8      <asp:BoundField DataField="PostalCode" HeaderText="PostalCode" SortExpression="PostalCode" />

   9       <asp:BoundField DataField="rowguid" HeaderText="rowguid" SortExpression="rowguid" />

   10     <asp:BoundField DataField="ModifiedDate" HeaderText="ModifiedDate" SortExpression="ModifiedDate" DataFormatString="{0:d}" HtmlEncode="false" />

   11  </Columns>

   12 </asp:GridView>

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


ASP.NET의 정규식 | ASP.NET
2004.10.20 22:53
김석곤(sukkon) http://cafe.naver.com/krdn/63

ASP.NET의 정규식

출처 : http://www.microsoft.com/korea/msdn/library/dnaspp/html/regexnet.asp

충돌 과정

Steven A. Smith

2004년 3월

적용 대상:
   Microsoft .NET Framework
   Microsoft ASP.NET
   정규식 API

요약: 정규식은 텍스트로 작업할 때 매우 유용한 도구입니다. 사용자 입력의 유효성을 검사해야 하거나, 문자열 내의 패턴을 검색해야 하거나, 효과적으로 텍스트 서식을 다시 지정해야 할 경우 정규식을 사용하면 좋습니다(14페이지/인쇄 페이지 기준).

이 기사의 소스 코드를 다운로드하십시오.

목차

소개
정규식 개요
단순식
한정사
메타 문자
문자 클래스
미리 정의된 메타 문자 집합
샘플 식
ASP.NET의 유효성 검사
정규식 API
무료 도구
고급 항목
결론
리소스
저자 소개

소개

Microsoft.NET Framework에서는 정규식을 완벽하게 지원하며, Microsoft ASP.NET 내에도 정규식 언어를 사용하는 컨트롤이 있습니다. 이 기사에서는 정규식의 기본 정보와 함께 자세한 내용을 참조할 수 있는 추가 정보를 다룹니다.

이 기사는 정규식에 대해서는 잘 몰라도 ASP.NET 및 .NET의 프로그래밍에는 익숙한 초급자를 위해 쓰여졌습니다. 이전에 정규식을 사용해 본 개발자들도 정규식 요약 과 함께 이 기사를 편리하게 참조하고 정보를 새롭게 상기할 수 있기를 바랍니다. 이 기사에서는 다음 내용을 다룹니다.

  1. 정규식 개요
  2. 단순식
  3. 한정사
  4. 메타 문자
  5. 문자 클래스
  6. 미리 정의된 메타 문자 집합
  7. 샘플 식 세부 정보
  8. ASP.NET의 유효성 검사
  9. 정규식 API
  10. 무료 도구
  11. 고급 항목 개요
  12. 요약 및 추가 리소스

이 기사나 정규식에 대한 일반적인 의문 사항이 있을 경우 350명 이상의 가입자를 보유한 http://www.aspadvice.com/ regex 메일 그룹 에서 질문하십시오.

정규식 개요

오늘날 사용되는 정규식은 1950대에 고안되었습니다. 원래 정규식은 신경 생리학자들의 연구 시 패턴이었던 "정규 집합"을 설명하는 데 사용되었습니다. 최초로 정규식을 만든 사람은 수학자 Stephen Kleene입니다. 이후에 Ken Thompson은 매우 일반적인 텍스트 유틸리티인 QED 및 GREP에 정규식을 도입했습니다. Jeffrey Friedl은 그의 저서 Mastering Regular Expressions(2판)에서 더 심도 있게 다루었습니다. 정규식의 이론과 개요에 대해 자세히 배우려는 분들께 이 책을 권장합니다.

지난 50년 동안 정규식은 불명확한 수학적 개념에서 많은 도구와 소프트웨어 패키지의 주요 기능으로 서서히 변화해 왔습니다. 수십 년 동안 많은 UNIX 도구에서 정규식을 지원했지만 정규식이 대부분의 Windows 개발자 도구 키트로서 제대로 자리잡기 시작한 것은 10년 정도 밖에 되지 않았습니다. Microsoft Visual Basic 6 또는 Microsoft VBScript에서는 정규식을 사용하기가 다소 불편했지만 새로 출시된 .NET Framework에서는 정규식을 완벽하게 지원하게 되어 모든 Microsoft 개발자가 모든 .NET 언어에 정규식을 사용할 수 있게 되었습니다.

그러면 정규식이란 무엇일까요? 정규식은 텍스트 문자열에서 패턴을 명시적으로 설명하는 데 사용할 수 있는 언어입니다. 이러한 패턴을 단순히 설명하는 것 외에도 일반적으로 정규식 엔진을 사용하면 일치 항목을 반복하거나 패턴을 구분 기호로 사용하여 문자열을 하위 문자열로 구문 분석하거나 지능적인 방식으로 텍스트를 바꾸거나 형식을 다시 지정할 수 있습니다. 또한 정규식을 사용하여 강력하고 간단한 방식으로 텍스트 처리와 관련된 많은 일반 작업을 해결할 수 있습니다.

정규식에 대해 설명할 때는 정규식과 일치하거나 일치하지 않는 텍스트를 기준으로 분석하는 것이 일반적입니다. 이 기사와 System.Text.RegularExpressions 클래스에서는 정규식 상호 작용의 3가지 항목인 정규식 패턴, 입력 문자열 및 패턴이 문자열 내에 만드는 일치에 대해 설명하도록 하겠습니다.

단순식

가장 단순한 정규식은 이미 친숙해 있는 정규식인 리터럴 문자열입니다. 특정 문자열을 문자 그대로 설명할 수 있으므로 foo와 같은 정규식 패턴은 입력 문자열 foo와 정확히 한 번 일치합니다. 이러한 경우 이 문자열은 The food was quite tasty 입력과도 일치합니다. 그러나 정확히 일치하는 항목만 찾을 경우 이 입력을 원하지 않을 수 있습니다.

물론 자신과 정확히 일치하는 문자열을 찾는 것은 일반적인 정규식 구현의 결과일 뿐 강력한 기능이라고 말할 수는 없습니다. foo 대신 f로 시작하는 모든 단어를 찾으려는 경우 또는 3자로 된 단어를 찾으려는 경우는 어떨까요? 이 정도 조건이라면 이미 리터럴 문자열로 수행할 수 있는 작업의 범위는 넘어 선 것입니다. 이제 정규식에 대해 더 자세히 배워야 합니다. 다음은 샘플 리터럴 표현식 및 일치하는 일부 입력입니다.

패턴 입력(일치 항목)
foo foo, food, foot, "There's evil afoot."

한정사

한정사를 사용하면 패턴 내에 특정 문자 또는 문자 집합을 반복할 수 있는 횟수를 간단히 지정할 수 있습니다. 다음과 같은 3가지 비명시적 한정사가 있습니다.

  1. *는 "0개 이상의 항목"을 나타냅니다.
  2. +는 "1개 이상의 항목"을 나타냅니다.
  3. ?는 "0개 또는 1개의 항목"을 나타냅니다.

한정사는 항상 한정사 바로 앞(왼쪽)에 있는 패턴을 참조합니다. 패턴 그룹을 만드는 데 괄호가 사용되지 않은 경우 이 한정사는 일반적으로 단일 문자입니다. 다음은 몇 가지 샘플 패턴 및 일치하는 입력입니다.

패턴 입력(일치 항목)
fo* foo, foe, food, fooot, "forget it", funny, puffy
fo+ foo, foe, food, foot, "forget it"
fo? foo, foe, food, foot, "forget it", funny, puffy

주어진 패턴이 정확히 0번 또는 한 번 발생할 수 있도록 지정하는 것 외에도 ? 문자는 입력 문자열에서 여러 개가 일치할 수 있을 경우 패턴 또는 하위 패턴이 최소 문자 수와 일치하도록 지정합니다.

비명시적 한정사(일반적으로 간단히 한정사라고 하지만 다음 그룹과 구분하기 위함) 외에도 명시적 한정사가 있습니다. 한 가지 패턴으로 발생할 수 있는 횟수와 관련하여 한정사가 모호할 경우 명시적 한정사를 사용하면 정확한 수, 범위 또는 숫자 집합을 지정할 수 있습니다. 정규 한정사와 같이 명시적 한정사는 적용되는 패턴 다음에 위치합니다. 명시적 한정사는 중괄호{} 및 숫자 값을 사용하여 이 괄호 안에 상한 및 하한 발생 수를 지정합니다. 예를 들어 x{5}는 x 문자 5개(xxxxx)와 일치합니다. 숫자 한 개만 지정한 경우 x{5,}와 같이 뒤에 쉼표를 입력하지 않는 한 상한으로 사용됩니다(개수에 상관없이 4개 이상의 x 문자와 일치).

패턴 입력(일치 항목)
ab{2}c abbc, aaabbccc
ab{,2}c ac, abc, abbc, aabbcc
ab{2,3}c abbc, abbbc, aabbcc, aabbbcc

메타 문자

정규식에서 특별한 의미가 있는 구성을 메타 문자라고 합니다. 앞서*, ?, +, { } 문자 등의 여러 메타 문자에 대해 이미 살펴 보았습니다. 기타 여러 문자는 정규식의 언어로 특별한 의미가 있습니다. 이러한 문자에는 $ ^ . [ ( | ) ] \ 등이 있습니다.

.(마침표 또는 점) 메타 문자는 가장 단순하면서도 가장 많이 사용되는 문자 중 하나입니다. 이 문자는 어떤 단일 문자와도 일치하며, 특정 패턴에 문자 조합이 포함될 수 있지만 한정사를 사용하여 특정 길이 범위 내에 속하도록 지정하는 데 유용합니다. 또한 긴 문자열 내에서 설명하는 패턴의 인스턴스에 식이 일치하는 것도 살펴 보았습니다. 그러나 패턴과 정확히 일치하도록 하려면 어떻게 해야 할까요? 이러한 경우는 우편 번호나 전화 번호에 적합한 형식으로 입력했는지 확인하는 경우와 같이 유효성 검사 시나리오에 자주 일어납니다. ^ 메타 문자는 문자열 또는 줄의 처음을 지정하는 데 사용되며 $ 메타 문자는 문자열이나 줄의 끝을 지정하는 데 사용됩니다. 이러한 문자를 패턴의 처음과 끝에 추가하면 패턴에 정확히 일치하는 입력 문자열에만 일치하도록 할 수 있습니다. 또한 ^ 메타 문자는 대괄호 [ ]로 지정되는 문자 클래스의 처음에 사용될 경우 특별한 의미가 있습니다. 이 내용은 아래에서 설명하겠습니다.

\(백슬래시) 메타 문자는 문자가 특별한 의미를 가지지 않도록 하는 데 사용되며 미리 정의된 메타 문자 집합의 인스턴스를 지정하는 데 사용됩니다. 이 내용도 아래에서 설명하겠습니다. 정규식이 메타 문자의 리터럴 버전을 포함하도록 하려면 백슬래시를 사용하여 특정 의미를 해제해야 합니다. 그러므로 인스턴스에 대해 "c:\"로 시작하는 문자열과 일치시키려는 경우 ^c:\\를 사용할 수 있습니다. 여기서 ^ 메타 문자를 사용하여 문자열이 이 패턴으로 시작되도록 지정했으며 백슬래시 메타 문자를 사용하여 리터럴 백슬래시를 해제했다는 점에 유의하십시오.

|(파이프) 메타 문자는 교체에 사용되며 기본적으로 패턴에서 'A 또는 B'를 지정합니다. 그러므로 a|b와 같은 입력은 'a' 또는 'b'가 포함된 어떤 내용에도 일치하며 문자 클래스 [ab]와 매우 비슷합니다.

마지막으로, 괄호 ( )는 패턴을 그룹화하는 데 사용됩니다. 가독성만을 위해 한정사를 사용하여 전체 패턴이 여러 번 발생하도록 허용하거나 입력의 특정 부분이 개별적으로 일치하도록 하여 서식을 다시 지정하거나 구문 분석을 수행하기 위해 패턴을 그룹화할 수 있습니다.

다음은 메타 문자 사용의 예를 보여 줍니다.

패턴 입력(일치 항목)
. a, b, c, 1, 2, 3
.* Abc, 123, 모든 문자열, 심지어 문자가 없어도 일치
^c:\\ c:\windows, c:\\\\\, c:\foo.txt, c:\ 다음에 오는 임의의 문자
abc$ abc, 123abc, abc로 끝나는 모든 문자열
(abc){2,3} abcabc, abcabcabc

문자 클래스

문자 클래스는 대괄호 [ ]로 둘러 쌓여 정의되는 것으로, 정규식 내의 소언어입니다. 가장 단순한 문자 클래스는 [aeiou]와 같이 단순히 괄호 안에 있는 문자 목록입니다. 식 안에 사용할 경우 이러한 문자 중 하나를 패턴 내의 이 위치에 사용할 수 있습니다. 그러나 한정사를 사용하지 않을 경우에 한하여 한 번만 사용할 수 있습니다. 문자 클래스를 사용할 경우 단어나 패턴은 정의할 수 없으며 단일 문자만 정의할 수 있습니다.

숫자를 지정하려면 문자 클래스 [0123456789]를 사용할 수 있습니다. 그러나 이렇게 길게 쓰면 오히려 사용하기 불편할 수 있으므로 하이픈 문자(-)를 사용하여 괄호 안에 문자 범위를 정의할 수 있습니다. 이 하이픈 문자는 문자 클래스에서만 특별한 의미가 있을 뿐 정규식에서는 별다른 의미가 없으므로 정규식 메타 문자로 정확히 한정하지는 않습니다. 또한 문자 클래스에서도 첫 문자가 아닌 경우에만 특별한 의미가 있습니다. 하이픈을 사용하여 숫자를 지정하려면 [0-9]를 사용합니다. 마찬가지로 소문자의 경우 [a-z]를 사용하고 대문자의 경우 [A-Z]를 사용하면 됩니다. 하이픈으로 정의되는 범위는 사용 중인 문자 집합에 따라 다르므로 ASCII 또는 유니코드 테이블 등에서의 문자 순서는 해당 범위에 포함되는 문자를 결정합니다. 범위에 하이픈을 포함해야 할 경우에는 첫 문자로 지정합니다. 예를 들어 [-.? ]는 이 4개 문자 중 하나와 일치합니다(마지막 문자는 공백). 또한 정규식 메타 문자는 문자 클래스 내에서 특별하게 처리되지 않으므로 의미를 해제할 필요가 없습니다. 문자 클래스는 고유 규칙과 구문을 사용하므로 나머지 정규식과는 다른 별도의 언어로 간주해야 합니다.

또한 문자 클래스에서 캐럿(^)을 첫 문자로 사용하여 문자 클래스를 빼면 문자 클래스의 구성원을 제외하고 임의의 문자를 일치시킬 수 있습니다. 그러므로 모음이 아닌 문자를 일치시키려면 [^aAeEiIoOuU]와 같은 문자 클래스를 사용할 수 있습니다. 하이픈을 빼려는 경우 [^-]과 같이 문자 클래스에서 두 번째 문자로 입력해야 합니다. 문자 클래스에서 ^ 문자는 정규식 패턴의 첫 문자로 사용할 때와 전혀 다른 의미를 가진다는 점에 유의하십시오.

다음은 사용 중인 문자 클래스의 예를 보여 줍니다.

패턴 입력(일치 항목)
^b[aeiou]t$ Bat, bet, bit, bot, but
^[0-9]{5}$ 11111, 12345, 99999
^c:\\ c:\windows, c:\\\\\, c:\foo.txt, c:\ 다음에 오는 임의의 문자
abc$ abc, 123abc, abc로 끝나는 모든 문자열
(abc){2,3} abcabc, abcabcabc
^[^-][0-9]$ 0, 1, 2, … (-0, -1, -2 등과 일치하지 않음)

다음 버전의 .NET Framework에서 새 기능인 코드 이름 "Whidbey"가 문자 클래스 빼기라는 문자 클래스에 추가될 예정입니다. 기본적으로 이 기능을 사용하면 한 문자 클래스에서 다른 문자 클래스를 뺄 수 있으므로 일부 패턴을 보다 편리하게 설명할 수 있습니다. 이 지정 사항은 현재http://www.gotdotnet.com/team/clr/bcl/TechArticles/techarticles/Specs/Regex/ CharacterClassSubtraction.doc 에서 볼 수 있습니다. 모든 소문자와 일치하는 구문은 [a-z-[aeiou]]와 같습니다.

미리 정의된 메타 문자 집합

지금까지 설명한 도구를 사용하여 수많은 작업을 수행할 수 있습니다. 그러나 패턴에서 모든 숫자에 대해 [0-9]라고 사용하는 것도 길다고 볼 수 있으며 영숫자 문자에서 [0-9a-zA-Z]와 같이 사용할 경우에는 더 불편합니다. 이와 같이 일반적이지만 매우 긴 패턴의 불편함을 없애기 위해 메타 문자 집합을 미리 정의했습니다. 정규식을 다르게 구현하면 미리 정의된 메타 문자 집합도 다르게 정의됩니다. 여기서 설명하는 메타 문자 집합은 .NET Framework의 System.Text.RegularExpressions API에서 지원됩니다. 미리 정의된 이러한 메타 문자의 표준 구문은 백슬래시(\) 다음에 하나 이상의 문자를 입력하는 것입니다. 대부분의 미리 정의된 메타 문자 길이는 문자 하나이므로 쉽게 사용할 수 있고 긴 문자 클래스 대신에 편리하게 사용할 수 있습니다. 두 가지 예로, 임의의 숫자와 일치하는 \d와 단어 문자(영숫자와 밑줄)와 일치하는 \w가 있습니다. 유니코드 캐리지 리턴 문자와 일치하는 \u000D와 같이, 일치하는 문자의 주소를 지정해야 하는 특수 문자 코드 일치는 예외입니다. 가장 일반적으로 사용하는 문자 클래스와 해당 메타 문자는 다음과 같습니다.

메타 문자 해당 문자 클래스
\a 벨(경보)과 일치합니다. \u0007
\b 문자 클래스 안에 사용되는 경우를 제외하고 단어 경계와 일치합니다. 백슬래시 문자 \u0008과 일치합니다.
\t 탭과 일치합니다. \u0009
\r 캐리지 리턴과 일치합니다. \u000D
\w 세로 탭과 일치합니다. \u000B
\f 용지 공급과 일치합니다. \u000C
\n 새 행과 일치합니다. \u000A
\e 이스케이프와 일치합니다. \u001B
\040 세 자리 8진수를 사용하는 ASCII 문자와 일치합니다. \040은 공백을 나타냅니다(십진수 32).
\x20 두 자리 16진수를 사용하는 ASCII 문자와 일치합니다. 이 경우 \x2-는 공백을 나타냅니다.
\cC ASCII 컨트롤 문자와 일치합니다. 이 경우 ctrl-C입니다.
\u0020 정확히 4자리 16진수를 사용하는 유니코드 문자와 일치합니다. 이 경우 \u0020은 공백입니다.
\* 미리 정의된 문자 클래스를 나타내지 않는 문자는 단순히 해당 문자로 처리됩니다. 그러므로 \*\x2A와 같습니다(*는 메타 문자가 아니라 리터럴임).
\p{name} 명명된 문자 클래스 'name'에 있는 임의의 문자와 일치합니다. 지원되는 이름은 유니코드 그룹 및 블록 범위입니다. 예를 들어 Ll, Nd, Z, IsGreek, IsBoxDrawing 및 Sc(통화)와 같습니다.
\P{name} 명명된 문자 클래스 'name'에 포함되지 않은 텍스트와 일치합니다.
\w 임의의 단어 문자와 일치합니다. 비유니코드 및 ECMAScript 구현의 경우 [a-zA-Z_0-9]와 같습니다. 유니코드 범주에서는 [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]와 같습니다.
\W \w를 빼고, ECMAScript 규격 집합 [^a-zA-Z_0-9] 또는 유니코드 문자 범주 [^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]와 같습니다.
\s 공백 문자와 일치합니다. 유니코드 문자 클래스 [\f\n\r\t\v\x85\p{Z}]와 같습니다. ECMAScript 옵션을 사용하여 ECMAScript 규격 동작을 지정한 경우 \s는 [ \f\n\r\t\v](선행 공백이 있음)와 같습니다.
\S 공백이 아닌 문자와 일치합니다. 유니코드 문자 범주 [^\f\n\r\t\v\x85\p{Z}]와 같습니다. ECMAScript 옵션을 사용하여 ECMAScript 규격 동작을 지정한 경우 \S는 [^ \f\n\r\t\v](^ 다음에 공백이 있음)와 같습니다.
\d 십진수와 일치합니다. 유니코드의 경우 [\p{Nd}]와 같고, 비유니코드 ECMAScript 동작의 경우 [0-9]와 같습니다.
\D 십진수가 아닌 숫자와 일치합니다. 유니코드의 경우 [\P{Nd}]와 같고, 비유니코드 ECMAScript 동작의 경우 [^0-9]와 같습니다.

샘플 식

대부분의 경우 예를 들어 설명할 때 가장 효과적으로 이해할 수 있으므로 여기서 몇 가지 샘플 식을 보여 드리겠습니다. 더 많은 샘플 식을 보려면 온라인 정규식 라이브러리 http://www.regexlib.com/ 을 방문하십시오.

패턴 설명
^\d{5}$ 미국 우편 번호와 같은 5자리 숫자입니다.
^(\d{5})|(\d{5}-\d{4}$ 5자리 숫자 또는 5자리 숫자-대시-4자리 숫자입니다. 미국 우편 번호 또는 미국 우편 번호+4 형식과 일치합니다.
^(\d{5}(-\d{4})?$ 앞의 예와 같지만 더 효율적입니다. ?를 사용하면 교체를 통해 별도의 패턴 두 개를 개별적으로 비교해야 하는 대신에 패턴의 4자리 부분을 선택적으로 입력할 수 있습니다.
^[+-]?\d+(\.\d+)?$ 실수와 일치하며 선택적으로 기호를 사용할 수 있습니다.
^[+-]?\d*\.?\d*$ 위의 예와 같지만 빈 문자열에도 일치합니다.
^(20|21|22|23|[01]\d)[0-5]\d$ 24시간 값과 일치합니다.
/\*.*\*/ C 스타일 주석 /* … */의 내용과 일치합니다.

ASP.NET의 유효성 검사

ASP.NET에서는 이전 ASP(또는 클래식 ASP)를 사용할 때보다 훨씬 쉽게 웹 양식 입력의 유효성을 검사하는 유효성 검사 컨트롤 집합을 제공합니다. 가장 강력한 유효성 검사기 중 하나는 RegularExpressionValidator입니다. 이 검사기는 입력과 일치해야 하는 정규식을 제공하여 입력의 유효성을 검사할 수 있습니다. 정규식 패턴은 컨트롤의 ValidationExpression 속성을 설정하여 지정합니다. 다음은 우편 번호 필드의 유효성 검사기 예를 보여 줍니다.

<asp:RegularExpressionValidator runat="server" id="ZipCodeValidator" 
ControlToValidate="ZipCodeTextBox" ErrorMessage="잘못된 우편 번호입니다. 
format; format should be either 12345 or 12345-6789."  
ValidationExpression="(\d{5}(-\d{4})?" />
(참고: 프로그래머 코멘트는 샘플 프로그램 파일에는 영문으로 제공되며 기사에는 설명을 위해
번역문으로 제공됩니다.)

다음은 RegularExpressionValidator에 대해 알아 두어야 할 사항입니다.

  • 유효성 검사 중인 컨트롤에서 빈 문자열로 활성화할 수 없습니다. RequiredFieldValidator에서만 빈 문자열을 인식합니다.
  • 문자열의 처음과 끝에 일치 문자 ^$가 가정되므로 따로 지정할 필요가 없습니다. 하지만 단지 불필요한 것일 뿐 이 문자를 추가해도 손상되거나 변경되는 것은 없습니다.
  • 모든 유효성 검사 컨트롤과 마찬가지로 이 유효성 검사는 클라이언트 쪽과 서버 쪽 모두에서 수행됩니다. 정규식이 ECMAScript 규격이 아닌 경우 클라이언트에서 실패합니다. 이 문제를 방지하려면 식이 ECMAScript 규격인지 확인하거나 서버에서만 유효성 검사를 수행하도록 컨트롤을 설정합니다.

정규식 API

ASP.NET 유효성 검사 컨트롤을 제외하고 .NET에서 정규식을 사용하는 대부분의 경우 System.Text.RegularExpressions 네임스페이스에 있는 클래스를 사용합니다. 특히 잘 알고 있어야 하는 주요 클래스는 Regex, MatchMatchCollection입니다.

중요하지 않은 문제이지만, 정규식의 약어인 regex를 /reg-eks/로 발음할 것인지 또는 /rej-eks/로 발음할 것인지에 관한 란이 있습니다. 개인적으로 후자를 선호하지만 두 가지 경우 모두 전문가들이 주장하고 있으므로 원하는 발음을 사용하면 됩니다.

Regex 클래스에는 풍부한 메서드와 속성이 있습니다. 이전에 이 클래스를 사용해 본 적이 없을 경우 약간 어렵다고 생각할 수도 있을 것입니다. 다음은 가장 자주 사용되는 메서드를 요약한 것입니다.

메서드 설명
Escape / Unescape 식에서 리터럴로 사용하기 위해 문자열에서 메타 문자 의미를 해제합니다.
IsMatch 입력 문자열에서 일치하는 항목을 찾을 경우 True를 반환합니다.
Match 입력 문자열에서 일치하는 항목을 찾을 경우 Match 개체를 반환합니다.
Matches 입력 문자열에서 찾은 일치 항목이 모두 포함된 MatchCollection 개체를 반환합니다.
Replace 입력 문자열에서 일치하는 항목을 지정된 바꾸기 문자열로 바꿉니다.
Split 입력 문자열을 regex 일치 항목으로 구분하여 배열 요소로 나눔으로써 문자열 배열을 반환합니다.

많은 메서드 외에도, 주로 Regex 개체의 생성자에서 지정할 수 있는 수많은 옵션이 있습니다. 이러한 옵션은 비트 마스크의 일부이므로 OR를 사용할 수 있습니다. 즉, Multiline과 Singleline을 동시에 사용할 수 있습니다.

옵션 설명
Compiled 루프에서 많은 일치 작업을 수행할 경우 이 옵션을 사용합니다. 이 옵션을 사용하면 각 반복 작업에서 식의 구문 분석 단계를 줄일 수 있습니다.
Multiline 입력 문자열에 몇 줄이 있는지와 아무 상관이 없습니다. 오히려 이 옵션은 단순히 ^$의 동작을 수정하므로 전체 입력 문자열의 시작과 끝 대신 BOL 및 EOL과 일치합니다.
IgnoreCase 패턴에서 검색 문자열을 일치시킬 때 대/소문자를 무시합니다.
IgnorePatternWhitespace 패턴에 원하는 수만큼 공백을 넣을 수 있으며 (?# comment #) 구문을 사용하여 패턴 내 주석을 사용할 수 있게 합니다.
SingleLine 입력 문자열에 몇 줄이 있는지와 아무 상관이 없습니다. 오히려 .(마침표) 메타 문자가 \n을 제외하고 모든 문자와 일치(기본값)하는 대신, 임의의 문자와 일치하도록 만듭니다.

정규식을 사용할 수 있는 몇 가지 일반적인 작업에는 유효성 검사, 일치 및 바꾸기가 있습니다. 대부분의 경우 이 작업은 Regex 클래스의 정적 메서드를 사용하여 수행할 수 있으며 Regex 클래스 자체를 인스턴스화할 필요가 없습니다. 유효성 검사를 수행하려면 올바른 식을 만들거나 찾아서 Regex 클래스의 IsMatch() 메서드를 사용하여 입력 문자열에 적용하기만 하면 됩니다. 예를 들어 다음 함수는 정규식을 사용하여 우편 번호의 유효성을 검사하는 방법을 보여 줍니다.

private void ValidateZipButton_Click(object sender, System.EventArgs e)
{
   String ZipRegex = @"^\d{5}$";
   if(Regex.IsMatch(ZipTextBox.Text, ZipRegex))
   {
      ResultLabel.Text = "우편 번호가 유효합니다!";
   }
   else
   {
      ResultLabel.Text = "우편 번호가 잘못되었습니다!";
   }
}

마찬가지로, 다음과 같이 정적 Replace() 메서드를 사용하여 일치하는 항목을 특정 문자열로 바꿀 수 있습니다.

String newText = Regex.Replace(inputString, pattern, replacementText);

마지막으로, 다음과 같은 코드를 사용하여 입력 문자열에서 일치하는 항목 집합을 반복할 수 있습니다.

private void MatchButton_Click(object sender, System.EventArgs e)
{
   MatchCollection matches = Regex.Matches(SearchStringTextBox.Text, 
MatchExpressionTextBox.Text);
   MatchCountLabel.Text = matches.Count.ToString();
   MatchesLabel.Text = "";
   foreach(Match match in matches)
   {
      MatchesLabel.Text += "Found " + match.ToString() + " at 
position " + match.Index + ".<br>";
   }
}

기본 동작 외에 다른 동작을 지정해야 할 경우 일반적으로 Regex 클래스의 인스턴스를 인스턴스화해야 합니다. 특히 설정 옵션의 경우가 그렇습니다. 예를 들어 대/소문자와 패턴 공백을 무시하는 Regex 인스턴스를 만들고 해당 식에 대해 일치하는 항목 집합을 검색하려면 다음 코드를 사용합니다.

Regex re = new Regex(pattern, 
   RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
MatchCollection mc = re.Matches(inputString);

이 샘플의 전체 작업 버전은 다운로드한 이 기사에 단순 ASP.NET 페이지로 포함되어 있습니다.

무료 도구

Regulator(http://royo.is-a-geek.com/iserializable/regulator/ ) - 클라이언트 쪽에서 실행하도록 만들어진 정규식 테스트 도구로서, 웹 서비스를 통해 RegexLib과 통합되며 일치, 분할, 바꾸기 등을 지원합니다. 성능 분석 및 구문 강조가 포함됩니다.

RegexDesigner.NET(http://www.sellsbrothers.com/tools/ ) - 정규식을 구성하고 테스트할 수 있는 강력한 비주얼 도구입니다. C# 및/또는 VB.NET 코드 및 컴파일된 어셈블리를 생성하여 식을 응용 프로그램에 쉽게 통합할 수 있게 합니다.

Regular Expression Workbench v2.0(http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=C712F2DF-B026-4D58-8961-4EE2729D7322 ) - 정규식을 만들고 테스트하고 연구할 수 있는 Eric Gunnerson의 도구입니다. 마우스로 regex를 가리켜 그 의미를 디코딩할 수 있는 "Examine-o-matic" 기능이 들어 있습니다.

고급 항목

여기서 주목할 만한 두 가지의 정규식 기능은 명명된 그룹 및 둘러보기 처리(lookaround processing)입니다. 하지만 이 두 가지 항목은 자주 사용되는 것이 아니므로 여기서는 간략하게만 설명하겠습니다.

명명된 그룹을 사용할 경우 일치하는 개별 그룹에 이름을 지정하고 식 내에서 프로그래밍 방식으로 이러한 그룹을 참조할 수 있습니다. 입력 문자열에서 요소의 순서와 배치를 다시 정렬하여 입력 문자열의 서식을 바꿀 때 Replace 메서드와 함께 사용하면 특히 유용합니다. 예를 들어 MM/DD/YYYY 문자열 형식으로 지정된 날짜를 DD-MM-YYYY 형식으로 바꾸려는 경우를 가정해 봅니다. 첫 번째 형식을 캡처하고 해당 Matches 컬렉션을 반복한 다음 문자열 처리를 사용하는 식을 써서 바꾸기 문자열을 만들 수 있습니다. 이 식에는 어느 정도의 코드 및 처리가 필요합니다. 명명된 그룹을 사용하여 이와 같은 작업을 수행할 수 있습니다.

String MDYToDMY(String input)
{
   return Regex.Replace(intput, 
@"\b(?<month>\d{1,2})/(?<day>\d{1,2}/(?<year>\d{4})\b",
"${day}-${month}-${year}"); }

또한 이름뿐 아니라 번호로도 그룹을 참조할 수 있습니다. 모든 이벤트에서 이러한 참조를 역참조라고 합니다. 또한 일반적으로 역참조는 반복되는 문자를 찾기 위한 [a-z]\1 식과 같이 일치하는 식 자체 내에서 많이 사용됩니다. 이 식은 'aa', 'bb', 'cc' 등과는 일치하지만 'ab', 'ac' 등 모든 두 글자 조합에 해당하거나 이를 허용하는 [a-z]{2} 또는 [a-z][a-z]와는 다릅니다. 역참조를 사용하면 식에서 이미 구문 분석하고 일치시킨 입력 문자열의 일부에 대해 기억할 수 있습니다.

"둘러보기 처리"는 많은 정규식 엔진에서 지원하는 긍정적, 부정적 예측 및 분석 기능을 참조합니다. 모든 정규식 엔진에서 둘러보기 처리의 모든 변형을 지원하는 것은 아닙니다. 이 구성은 문자와 일치할 수 있지만 문자를 사용하지는 않습니다. 일부 패턴은 둘러보기 처리를 사용하지 않고 설명할 수 없습니다. 특히 패턴 일부의 존재가 다른 부분의 존재에 따라 결정되는 경우에는 더욱 그렇습니다. 각 둘러보기 기능의 구문은 다음과 같습니다.

구문 설명
(?=…) 긍정적 예측(Positive Lookahead)
(?!...) 부정적 예측(Negative Lookahead)
(?<=…) 긍정적 분석(Positive Lookbehind)
(?<!...) 부정적 분석(Negative Lookbehind)

둘러보기 처리를 사용해야 하는 경우의 예로는 암호 유효성 검사가 있습니다. 적어도 숫자가 하나 이상 포함된 4자에서 8자 사이의 암호를 입력해야 하는 암호 제한을 가정해 봅니다. 일치 항목에 대해 \d를 테스트하고 문자열 작업을 사용하여 길이를 테스트함으로써 이 작업을 수행할 수 있지만 정규식에서 전체를 수행하려면 둘러보기가 필요합니다. 다음 식이 나타내는 것과 같이 특히 긍정적 예측의 경우 더욱 그렇습니다. ^(?=.*\d).{4,8}$

결론

정규식을 사용하면 텍스트의 패턴을 효과적으로 설명할 수 있으므로 문자열 유효성 검사와 처리를 위한 리소스로 활용할 수 있습니다. .NET Framework는 System.Text.RegularExpressions 네임스페이스를 비롯하여, 특히 Regex 클래스에서 정규식을 완벽하게 지원합니다. API는 사용하기가 간편하지만 올바른 정규식을 사용하는 것이 때로는 어려운 일입니다. 다행히 정규식은 재사용률이 매우 높으며 많은 온라인 리소스에서 다른 사용자가 지정한 식을 찾아서 활용할 수도 있고, 만들기 어려운 정규식에 대해 도움도 받을 수 있습니다.

리소스

정규식 라이브러리 http://www.regexlib.com/ 

정규식 토론 목록 http://aspadvice.com/login.aspx?ReturnUrl=%2fSignUp%2flist.aspx%3fl%3d68%26c%3d16&l=68&c=16 

정규식 포럼 http://forums.regexadvice.com/ 

정규식 웹 로그 http://blogs.regexadvice.com/ 

Jeffrey Friedl의 Mastering Regular Expressions(O'Reilly) http://www.regex.info/ 

.NET 정규식 참조 http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemTextRegularExpressions.asp 

Jscript 정규식 구문 http://www.msdn.microsoft.com/library/en-us/script56/html/js56jsgrpRegExpSyntax.asp 

정규식 정보 http://www.regular-expressions.info/ 

저자 소개

Microsoft ASP.NET MVP인 Steven A. Smith는 ASPAlliance.com 및 DevAdvice.com의 사장이자 소유자입니다. 또한 .NET 중심 교육 기관인 ASPSmith Ltd의 소유자이자 대표 강사로, MSDN 및 AspNetPRO 잡지에 실리는 기사뿐 아니라 ASP.NET Developer's Cookbook과 ASP.NET By Example 두 권의 책을 저술한 바 있습니다. 또한 매년 열리는 여러 회의에서 강연을 맡고 있고 INETA 강연자 협회의 회원이며, 경영학 석사 및 컴퓨터 과학 기술 학사 학위를 소지하고 있습니다.

전자 메일(ssmith@aspalliance.com)을 통해 저자와 연락할 수 있습니다.

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


ASP.NET의 정규식 | ASP.NET
2004.10.20 22:53
김석곤(sukkon) http://cafe.naver.com/krdn/63

ASP.NET의 정규식

출처 : http://www.microsoft.com/korea/msdn/library/dnaspp/html/regexnet.asp

충돌 과정

Steven A. Smith

2004년 3월

적용 대상:
   Microsoft .NET Framework
   Microsoft ASP.NET
   정규식 API

요약: 정규식은 텍스트로 작업할 때 매우 유용한 도구입니다. 사용자 입력의 유효성을 검사해야 하거나, 문자열 내의 패턴을 검색해야 하거나, 효과적으로 텍스트 서식을 다시 지정해야 할 경우 정규식을 사용하면 좋습니다(14페이지/인쇄 페이지 기준).

이 기사의 소스 코드를 다운로드하십시오.

목차

소개
정규식 개요
단순식
한정사
메타 문자
문자 클래스
미리 정의된 메타 문자 집합
샘플 식
ASP.NET의 유효성 검사
정규식 API
무료 도구
고급 항목
결론
리소스
저자 소개

소개

Microsoft.NET Framework에서는 정규식을 완벽하게 지원하며, Microsoft ASP.NET 내에도 정규식 언어를 사용하는 컨트롤이 있습니다. 이 기사에서는 정규식의 기본 정보와 함께 자세한 내용을 참조할 수 있는 추가 정보를 다룹니다.

이 기사는 정규식에 대해서는 잘 몰라도 ASP.NET 및 .NET의 프로그래밍에는 익숙한 초급자를 위해 쓰여졌습니다. 이전에 정규식을 사용해 본 개발자들도 정규식 요약 과 함께 이 기사를 편리하게 참조하고 정보를 새롭게 상기할 수 있기를 바랍니다. 이 기사에서는 다음 내용을 다룹니다.

  1. 정규식 개요
  2. 단순식
  3. 한정사
  4. 메타 문자
  5. 문자 클래스
  6. 미리 정의된 메타 문자 집합
  7. 샘플 식 세부 정보
  8. ASP.NET의 유효성 검사
  9. 정규식 API
  10. 무료 도구
  11. 고급 항목 개요
  12. 요약 및 추가 리소스

이 기사나 정규식에 대한 일반적인 의문 사항이 있을 경우 350명 이상의 가입자를 보유한 http://www.aspadvice.com/ regex 메일 그룹 에서 질문하십시오.

정규식 개요

오늘날 사용되는 정규식은 1950대에 고안되었습니다. 원래 정규식은 신경 생리학자들의 연구 시 패턴이었던 "정규 집합"을 설명하는 데 사용되었습니다. 최초로 정규식을 만든 사람은 수학자 Stephen Kleene입니다. 이후에 Ken Thompson은 매우 일반적인 텍스트 유틸리티인 QED 및 GREP에 정규식을 도입했습니다. Jeffrey Friedl은 그의 저서 Mastering Regular Expressions(2판)에서 더 심도 있게 다루었습니다. 정규식의 이론과 개요에 대해 자세히 배우려는 분들께 이 책을 권장합니다.

지난 50년 동안 정규식은 불명확한 수학적 개념에서 많은 도구와 소프트웨어 패키지의 주요 기능으로 서서히 변화해 왔습니다. 수십 년 동안 많은 UNIX 도구에서 정규식을 지원했지만 정규식이 대부분의 Windows 개발자 도구 키트로서 제대로 자리잡기 시작한 것은 10년 정도 밖에 되지 않았습니다. Microsoft Visual Basic 6 또는 Microsoft VBScript에서는 정규식을 사용하기가 다소 불편했지만 새로 출시된 .NET Framework에서는 정규식을 완벽하게 지원하게 되어 모든 Microsoft 개발자가 모든 .NET 언어에 정규식을 사용할 수 있게 되었습니다.

그러면 정규식이란 무엇일까요? 정규식은 텍스트 문자열에서 패턴을 명시적으로 설명하는 데 사용할 수 있는 언어입니다. 이러한 패턴을 단순히 설명하는 것 외에도 일반적으로 정규식 엔진을 사용하면 일치 항목을 반복하거나 패턴을 구분 기호로 사용하여 문자열을 하위 문자열로 구문 분석하거나 지능적인 방식으로 텍스트를 바꾸거나 형식을 다시 지정할 수 있습니다. 또한 정규식을 사용하여 강력하고 간단한 방식으로 텍스트 처리와 관련된 많은 일반 작업을 해결할 수 있습니다.

정규식에 대해 설명할 때는 정규식과 일치하거나 일치하지 않는 텍스트를 기준으로 분석하는 것이 일반적입니다. 이 기사와 System.Text.RegularExpressions 클래스에서는 정규식 상호 작용의 3가지 항목인 정규식 패턴, 입력 문자열 및 패턴이 문자열 내에 만드는 일치에 대해 설명하도록 하겠습니다.

단순식

가장 단순한 정규식은 이미 친숙해 있는 정규식인 리터럴 문자열입니다. 특정 문자열을 문자 그대로 설명할 수 있으므로 foo와 같은 정규식 패턴은 입력 문자열 foo와 정확히 한 번 일치합니다. 이러한 경우 이 문자열은 The food was quite tasty 입력과도 일치합니다. 그러나 정확히 일치하는 항목만 찾을 경우 이 입력을 원하지 않을 수 있습니다.

물론 자신과 정확히 일치하는 문자열을 찾는 것은 일반적인 정규식 구현의 결과일 뿐 강력한 기능이라고 말할 수는 없습니다. foo 대신 f로 시작하는 모든 단어를 찾으려는 경우 또는 3자로 된 단어를 찾으려는 경우는 어떨까요? 이 정도 조건이라면 이미 리터럴 문자열로 수행할 수 있는 작업의 범위는 넘어 선 것입니다. 이제 정규식에 대해 더 자세히 배워야 합니다. 다음은 샘플 리터럴 표현식 및 일치하는 일부 입력입니다.

패턴 입력(일치 항목)
foo foo, food, foot, "There's evil afoot."

한정사

한정사를 사용하면 패턴 내에 특정 문자 또는 문자 집합을 반복할 수 있는 횟수를 간단히 지정할 수 있습니다. 다음과 같은 3가지 비명시적 한정사가 있습니다.

  1. *는 "0개 이상의 항목"을 나타냅니다.
  2. +는 "1개 이상의 항목"을 나타냅니다.
  3. ?는 "0개 또는 1개의 항목"을 나타냅니다.

한정사는 항상 한정사 바로 앞(왼쪽)에 있는 패턴을 참조합니다. 패턴 그룹을 만드는 데 괄호가 사용되지 않은 경우 이 한정사는 일반적으로 단일 문자입니다. 다음은 몇 가지 샘플 패턴 및 일치하는 입력입니다.

패턴 입력(일치 항목)
fo* foo, foe, food, fooot, "forget it", funny, puffy
fo+ foo, foe, food, foot, "forget it"
fo? foo, foe, food, foot, "forget it", funny, puffy

주어진 패턴이 정확히 0번 또는 한 번 발생할 수 있도록 지정하는 것 외에도 ? 문자는 입력 문자열에서 여러 개가 일치할 수 있을 경우 패턴 또는 하위 패턴이 최소 문자 수와 일치하도록 지정합니다.

비명시적 한정사(일반적으로 간단히 한정사라고 하지만 다음 그룹과 구분하기 위함) 외에도 명시적 한정사가 있습니다. 한 가지 패턴으로 발생할 수 있는 횟수와 관련하여 한정사가 모호할 경우 명시적 한정사를 사용하면 정확한 수, 범위 또는 숫자 집합을 지정할 수 있습니다. 정규 한정사와 같이 명시적 한정사는 적용되는 패턴 다음에 위치합니다. 명시적 한정사는 중괄호{} 및 숫자 값을 사용하여 이 괄호 안에 상한 및 하한 발생 수를 지정합니다. 예를 들어 x{5}는 x 문자 5개(xxxxx)와 일치합니다. 숫자 한 개만 지정한 경우 x{5,}와 같이 뒤에 쉼표를 입력하지 않는 한 상한으로 사용됩니다(개수에 상관없이 4개 이상의 x 문자와 일치).

패턴 입력(일치 항목)
ab{2}c abbc, aaabbccc
ab{,2}c ac, abc, abbc, aabbcc
ab{2,3}c abbc, abbbc, aabbcc, aabbbcc

메타 문자

정규식에서 특별한 의미가 있는 구성을 메타 문자라고 합니다. 앞서*, ?, +, { } 문자 등의 여러 메타 문자에 대해 이미 살펴 보았습니다. 기타 여러 문자는 정규식의 언어로 특별한 의미가 있습니다. 이러한 문자에는 $ ^ . [ ( | ) ] \ 등이 있습니다.

.(마침표 또는 점) 메타 문자는 가장 단순하면서도 가장 많이 사용되는 문자 중 하나입니다. 이 문자는 어떤 단일 문자와도 일치하며, 특정 패턴에 문자 조합이 포함될 수 있지만 한정사를 사용하여 특정 길이 범위 내에 속하도록 지정하는 데 유용합니다. 또한 긴 문자열 내에서 설명하는 패턴의 인스턴스에 식이 일치하는 것도 살펴 보았습니다. 그러나 패턴과 정확히 일치하도록 하려면 어떻게 해야 할까요? 이러한 경우는 우편 번호나 전화 번호에 적합한 형식으로 입력했는지 확인하는 경우와 같이 유효성 검사 시나리오에 자주 일어납니다. ^ 메타 문자는 문자열 또는 줄의 처음을 지정하는 데 사용되며 $ 메타 문자는 문자열이나 줄의 끝을 지정하는 데 사용됩니다. 이러한 문자를 패턴의 처음과 끝에 추가하면 패턴에 정확히 일치하는 입력 문자열에만 일치하도록 할 수 있습니다. 또한 ^ 메타 문자는 대괄호 [ ]로 지정되는 문자 클래스의 처음에 사용될 경우 특별한 의미가 있습니다. 이 내용은 아래에서 설명하겠습니다.

\(백슬래시) 메타 문자는 문자가 특별한 의미를 가지지 않도록 하는 데 사용되며 미리 정의된 메타 문자 집합의 인스턴스를 지정하는 데 사용됩니다. 이 내용도 아래에서 설명하겠습니다. 정규식이 메타 문자의 리터럴 버전을 포함하도록 하려면 백슬래시를 사용하여 특정 의미를 해제해야 합니다. 그러므로 인스턴스에 대해 "c:\"로 시작하는 문자열과 일치시키려는 경우 ^c:\\를 사용할 수 있습니다. 여기서 ^ 메타 문자를 사용하여 문자열이 이 패턴으로 시작되도록 지정했으며 백슬래시 메타 문자를 사용하여 리터럴 백슬래시를 해제했다는 점에 유의하십시오.

|(파이프) 메타 문자는 교체에 사용되며 기본적으로 패턴에서 'A 또는 B'를 지정합니다. 그러므로 a|b와 같은 입력은 'a' 또는 'b'가 포함된 어떤 내용에도 일치하며 문자 클래스 [ab]와 매우 비슷합니다.

마지막으로, 괄호 ( )는 패턴을 그룹화하는 데 사용됩니다. 가독성만을 위해 한정사를 사용하여 전체 패턴이 여러 번 발생하도록 허용하거나 입력의 특정 부분이 개별적으로 일치하도록 하여 서식을 다시 지정하거나 구문 분석을 수행하기 위해 패턴을 그룹화할 수 있습니다.

다음은 메타 문자 사용의 예를 보여 줍니다.

패턴 입력(일치 항목)
. a, b, c, 1, 2, 3
.* Abc, 123, 모든 문자열, 심지어 문자가 없어도 일치
^c:\\ c:\windows, c:\\\\\, c:\foo.txt, c:\ 다음에 오는 임의의 문자
abc$ abc, 123abc, abc로 끝나는 모든 문자열
(abc){2,3} abcabc, abcabcabc

문자 클래스

문자 클래스는 대괄호 [ ]로 둘러 쌓여 정의되는 것으로, 정규식 내의 소언어입니다. 가장 단순한 문자 클래스는 [aeiou]와 같이 단순히 괄호 안에 있는 문자 목록입니다. 식 안에 사용할 경우 이러한 문자 중 하나를 패턴 내의 이 위치에 사용할 수 있습니다. 그러나 한정사를 사용하지 않을 경우에 한하여 한 번만 사용할 수 있습니다. 문자 클래스를 사용할 경우 단어나 패턴은 정의할 수 없으며 단일 문자만 정의할 수 있습니다.

숫자를 지정하려면 문자 클래스 [0123456789]를 사용할 수 있습니다. 그러나 이렇게 길게 쓰면 오히려 사용하기 불편할 수 있으므로 하이픈 문자(-)를 사용하여 괄호 안에 문자 범위를 정의할 수 있습니다. 이 하이픈 문자는 문자 클래스에서만 특별한 의미가 있을 뿐 정규식에서는 별다른 의미가 없으므로 정규식 메타 문자로 정확히 한정하지는 않습니다. 또한 문자 클래스에서도 첫 문자가 아닌 경우에만 특별한 의미가 있습니다. 하이픈을 사용하여 숫자를 지정하려면 [0-9]를 사용합니다. 마찬가지로 소문자의 경우 [a-z]를 사용하고 대문자의 경우 [A-Z]를 사용하면 됩니다. 하이픈으로 정의되는 범위는 사용 중인 문자 집합에 따라 다르므로 ASCII 또는 유니코드 테이블 등에서의 문자 순서는 해당 범위에 포함되는 문자를 결정합니다. 범위에 하이픈을 포함해야 할 경우에는 첫 문자로 지정합니다. 예를 들어 [-.? ]는 이 4개 문자 중 하나와 일치합니다(마지막 문자는 공백). 또한 정규식 메타 문자는 문자 클래스 내에서 특별하게 처리되지 않으므로 의미를 해제할 필요가 없습니다. 문자 클래스는 고유 규칙과 구문을 사용하므로 나머지 정규식과는 다른 별도의 언어로 간주해야 합니다.

또한 문자 클래스에서 캐럿(^)을 첫 문자로 사용하여 문자 클래스를 빼면 문자 클래스의 구성원을 제외하고 임의의 문자를 일치시킬 수 있습니다. 그러므로 모음이 아닌 문자를 일치시키려면 [^aAeEiIoOuU]와 같은 문자 클래스를 사용할 수 있습니다. 하이픈을 빼려는 경우 [^-]과 같이 문자 클래스에서 두 번째 문자로 입력해야 합니다. 문자 클래스에서 ^ 문자는 정규식 패턴의 첫 문자로 사용할 때와 전혀 다른 의미를 가진다는 점에 유의하십시오.

다음은 사용 중인 문자 클래스의 예를 보여 줍니다.

패턴 입력(일치 항목)
^b[aeiou]t$ Bat, bet, bit, bot, but
^[0-9]{5}$ 11111, 12345, 99999
^c:\\ c:\windows, c:\\\\\, c:\foo.txt, c:\ 다음에 오는 임의의 문자
abc$ abc, 123abc, abc로 끝나는 모든 문자열
(abc){2,3} abcabc, abcabcabc
^[^-][0-9]$ 0, 1, 2, … (-0, -1, -2 등과 일치하지 않음)

다음 버전의 .NET Framework에서 새 기능인 코드 이름 "Whidbey"가 문자 클래스 빼기라는 문자 클래스에 추가될 예정입니다. 기본적으로 이 기능을 사용하면 한 문자 클래스에서 다른 문자 클래스를 뺄 수 있으므로 일부 패턴을 보다 편리하게 설명할 수 있습니다. 이 지정 사항은 현재http://www.gotdotnet.com/team/clr/bcl/TechArticles/techarticles/Specs/Regex/ CharacterClassSubtraction.doc 에서 볼 수 있습니다. 모든 소문자와 일치하는 구문은 [a-z-[aeiou]]와 같습니다.

미리 정의된 메타 문자 집합

지금까지 설명한 도구를 사용하여 수많은 작업을 수행할 수 있습니다. 그러나 패턴에서 모든 숫자에 대해 [0-9]라고 사용하는 것도 길다고 볼 수 있으며 영숫자 문자에서 [0-9a-zA-Z]와 같이 사용할 경우에는 더 불편합니다. 이와 같이 일반적이지만 매우 긴 패턴의 불편함을 없애기 위해 메타 문자 집합을 미리 정의했습니다. 정규식을 다르게 구현하면 미리 정의된 메타 문자 집합도 다르게 정의됩니다. 여기서 설명하는 메타 문자 집합은 .NET Framework의 System.Text.RegularExpressions API에서 지원됩니다. 미리 정의된 이러한 메타 문자의 표준 구문은 백슬래시(\) 다음에 하나 이상의 문자를 입력하는 것입니다. 대부분의 미리 정의된 메타 문자 길이는 문자 하나이므로 쉽게 사용할 수 있고 긴 문자 클래스 대신에 편리하게 사용할 수 있습니다. 두 가지 예로, 임의의 숫자와 일치하는 \d와 단어 문자(영숫자와 밑줄)와 일치하는 \w가 있습니다. 유니코드 캐리지 리턴 문자와 일치하는 \u000D와 같이, 일치하는 문자의 주소를 지정해야 하는 특수 문자 코드 일치는 예외입니다. 가장 일반적으로 사용하는 문자 클래스와 해당 메타 문자는 다음과 같습니다.

메타 문자 해당 문자 클래스
\a 벨(경보)과 일치합니다. \u0007
\b 문자 클래스 안에 사용되는 경우를 제외하고 단어 경계와 일치합니다. 백슬래시 문자 \u0008과 일치합니다.
\t 탭과 일치합니다. \u0009
\r 캐리지 리턴과 일치합니다. \u000D
\w 세로 탭과 일치합니다. \u000B
\f 용지 공급과 일치합니다. \u000C
\n 새 행과 일치합니다. \u000A
\e 이스케이프와 일치합니다. \u001B
\040 세 자리 8진수를 사용하는 ASCII 문자와 일치합니다. \040은 공백을 나타냅니다(십진수 32).
\x20 두 자리 16진수를 사용하는 ASCII 문자와 일치합니다. 이 경우 \x2-는 공백을 나타냅니다.
\cC ASCII 컨트롤 문자와 일치합니다. 이 경우 ctrl-C입니다.
\u0020 정확히 4자리 16진수를 사용하는 유니코드 문자와 일치합니다. 이 경우 \u0020은 공백입니다.
\* 미리 정의된 문자 클래스를 나타내지 않는 문자는 단순히 해당 문자로 처리됩니다. 그러므로 \*\x2A와 같습니다(*는 메타 문자가 아니라 리터럴임).
\p{name} 명명된 문자 클래스 'name'에 있는 임의의 문자와 일치합니다. 지원되는 이름은 유니코드 그룹 및 블록 범위입니다. 예를 들어 Ll, Nd, Z, IsGreek, IsBoxDrawing 및 Sc(통화)와 같습니다.
\P{name} 명명된 문자 클래스 'name'에 포함되지 않은 텍스트와 일치합니다.
\w 임의의 단어 문자와 일치합니다. 비유니코드 및 ECMAScript 구현의 경우 [a-zA-Z_0-9]와 같습니다. 유니코드 범주에서는 [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]와 같습니다.
\W \w를 빼고, ECMAScript 규격 집합 [^a-zA-Z_0-9] 또는 유니코드 문자 범주 [^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]와 같습니다.
\s 공백 문자와 일치합니다. 유니코드 문자 클래스 [\f\n\r\t\v\x85\p{Z}]와 같습니다. ECMAScript 옵션을 사용하여 ECMAScript 규격 동작을 지정한 경우 \s는 [ \f\n\r\t\v](선행 공백이 있음)와 같습니다.
\S 공백이 아닌 문자와 일치합니다. 유니코드 문자 범주 [^\f\n\r\t\v\x85\p{Z}]와 같습니다. ECMAScript 옵션을 사용하여 ECMAScript 규격 동작을 지정한 경우 \S는 [^ \f\n\r\t\v](^ 다음에 공백이 있음)와 같습니다.
\d 십진수와 일치합니다. 유니코드의 경우 [\p{Nd}]와 같고, 비유니코드 ECMAScript 동작의 경우 [0-9]와 같습니다.
\D 십진수가 아닌 숫자와 일치합니다. 유니코드의 경우 [\P{Nd}]와 같고, 비유니코드 ECMAScript 동작의 경우 [^0-9]와 같습니다.

샘플 식

대부분의 경우 예를 들어 설명할 때 가장 효과적으로 이해할 수 있으므로 여기서 몇 가지 샘플 식을 보여 드리겠습니다. 더 많은 샘플 식을 보려면 온라인 정규식 라이브러리 http://www.regexlib.com/ 을 방문하십시오.

패턴 설명
^\d{5}$ 미국 우편 번호와 같은 5자리 숫자입니다.
^(\d{5})|(\d{5}-\d{4}$ 5자리 숫자 또는 5자리 숫자-대시-4자리 숫자입니다. 미국 우편 번호 또는 미국 우편 번호+4 형식과 일치합니다.
^(\d{5}(-\d{4})?$ 앞의 예와 같지만 더 효율적입니다. ?를 사용하면 교체를 통해 별도의 패턴 두 개를 개별적으로 비교해야 하는 대신에 패턴의 4자리 부분을 선택적으로 입력할 수 있습니다.
^[+-]?\d+(\.\d+)?$ 실수와 일치하며 선택적으로 기호를 사용할 수 있습니다.
^[+-]?\d*\.?\d*$ 위의 예와 같지만 빈 문자열에도 일치합니다.
^(20|21|22|23|[01]\d)[0-5]\d$ 24시간 값과 일치합니다.
/\*.*\*/ C 스타일 주석 /* … */의 내용과 일치합니다.

ASP.NET의 유효성 검사

ASP.NET에서는 이전 ASP(또는 클래식 ASP)를 사용할 때보다 훨씬 쉽게 웹 양식 입력의 유효성을 검사하는 유효성 검사 컨트롤 집합을 제공합니다. 가장 강력한 유효성 검사기 중 하나는 RegularExpressionValidator입니다. 이 검사기는 입력과 일치해야 하는 정규식을 제공하여 입력의 유효성을 검사할 수 있습니다. 정규식 패턴은 컨트롤의 ValidationExpression 속성을 설정하여 지정합니다. 다음은 우편 번호 필드의 유효성 검사기 예를 보여 줍니다.

<asp:RegularExpressionValidator runat="server" id="ZipCodeValidator" 
ControlToValidate="ZipCodeTextBox" ErrorMessage="잘못된 우편 번호입니다. 
format; format should be either 12345 or 12345-6789."  
ValidationExpression="(\d{5}(-\d{4})?" />
(참고: 프로그래머 코멘트는 샘플 프로그램 파일에는 영문으로 제공되며 기사에는 설명을 위해
번역문으로 제공됩니다.)

다음은 RegularExpressionValidator에 대해 알아 두어야 할 사항입니다.

  • 유효성 검사 중인 컨트롤에서 빈 문자열로 활성화할 수 없습니다. RequiredFieldValidator에서만 빈 문자열을 인식합니다.
  • 문자열의 처음과 끝에 일치 문자 ^$가 가정되므로 따로 지정할 필요가 없습니다. 하지만 단지 불필요한 것일 뿐 이 문자를 추가해도 손상되거나 변경되는 것은 없습니다.
  • 모든 유효성 검사 컨트롤과 마찬가지로 이 유효성 검사는 클라이언트 쪽과 서버 쪽 모두에서 수행됩니다. 정규식이 ECMAScript 규격이 아닌 경우 클라이언트에서 실패합니다. 이 문제를 방지하려면 식이 ECMAScript 규격인지 확인하거나 서버에서만 유효성 검사를 수행하도록 컨트롤을 설정합니다.

정규식 API

ASP.NET 유효성 검사 컨트롤을 제외하고 .NET에서 정규식을 사용하는 대부분의 경우 System.Text.RegularExpressions 네임스페이스에 있는 클래스를 사용합니다. 특히 잘 알고 있어야 하는 주요 클래스는 Regex, MatchMatchCollection입니다.

중요하지 않은 문제이지만, 정규식의 약어인 regex를 /reg-eks/로 발음할 것인지 또는 /rej-eks/로 발음할 것인지에 관한 란이 있습니다. 개인적으로 후자를 선호하지만 두 가지 경우 모두 전문가들이 주장하고 있으므로 원하는 발음을 사용하면 됩니다.

Regex 클래스에는 풍부한 메서드와 속성이 있습니다. 이전에 이 클래스를 사용해 본 적이 없을 경우 약간 어렵다고 생각할 수도 있을 것입니다. 다음은 가장 자주 사용되는 메서드를 요약한 것입니다.

메서드 설명
Escape / Unescape 식에서 리터럴로 사용하기 위해 문자열에서 메타 문자 의미를 해제합니다.
IsMatch 입력 문자열에서 일치하는 항목을 찾을 경우 True를 반환합니다.
Match 입력 문자열에서 일치하는 항목을 찾을 경우 Match 개체를 반환합니다.
Matches 입력 문자열에서 찾은 일치 항목이 모두 포함된 MatchCollection 개체를 반환합니다.
Replace 입력 문자열에서 일치하는 항목을 지정된 바꾸기 문자열로 바꿉니다.
Split 입력 문자열을 regex 일치 항목으로 구분하여 배열 요소로 나눔으로써 문자열 배열을 반환합니다.

많은 메서드 외에도, 주로 Regex 개체의 생성자에서 지정할 수 있는 수많은 옵션이 있습니다. 이러한 옵션은 비트 마스크의 일부이므로 OR를 사용할 수 있습니다. 즉, Multiline과 Singleline을 동시에 사용할 수 있습니다.

옵션 설명
Compiled 루프에서 많은 일치 작업을 수행할 경우 이 옵션을 사용합니다. 이 옵션을 사용하면 각 반복 작업에서 식의 구문 분석 단계를 줄일 수 있습니다.
Multiline 입력 문자열에 몇 줄이 있는지와 아무 상관이 없습니다. 오히려 이 옵션은 단순히 ^$의 동작을 수정하므로 전체 입력 문자열의 시작과 끝 대신 BOL 및 EOL과 일치합니다.
IgnoreCase 패턴에서 검색 문자열을 일치시킬 때 대/소문자를 무시합니다.
IgnorePatternWhitespace 패턴에 원하는 수만큼 공백을 넣을 수 있으며 (?# comment #) 구문을 사용하여 패턴 내 주석을 사용할 수 있게 합니다.
SingleLine 입력 문자열에 몇 줄이 있는지와 아무 상관이 없습니다. 오히려 .(마침표) 메타 문자가 \n을 제외하고 모든 문자와 일치(기본값)하는 대신, 임의의 문자와 일치하도록 만듭니다.

정규식을 사용할 수 있는 몇 가지 일반적인 작업에는 유효성 검사, 일치 및 바꾸기가 있습니다. 대부분의 경우 이 작업은 Regex 클래스의 정적 메서드를 사용하여 수행할 수 있으며 Regex 클래스 자체를 인스턴스화할 필요가 없습니다. 유효성 검사를 수행하려면 올바른 식을 만들거나 찾아서 Regex 클래스의 IsMatch() 메서드를 사용하여 입력 문자열에 적용하기만 하면 됩니다. 예를 들어 다음 함수는 정규식을 사용하여 우편 번호의 유효성을 검사하는 방법을 보여 줍니다.

private void ValidateZipButton_Click(object sender, System.EventArgs e)
{
   String ZipRegex = @"^\d{5}$";
   if(Regex.IsMatch(ZipTextBox.Text, ZipRegex))
   {
      ResultLabel.Text = "우편 번호가 유효합니다!";
   }
   else
   {
      ResultLabel.Text = "우편 번호가 잘못되었습니다!";
   }
}

마찬가지로, 다음과 같이 정적 Replace() 메서드를 사용하여 일치하는 항목을 특정 문자열로 바꿀 수 있습니다.

String newText = Regex.Replace(inputString, pattern, replacementText);

마지막으로, 다음과 같은 코드를 사용하여 입력 문자열에서 일치하는 항목 집합을 반복할 수 있습니다.

private void MatchButton_Click(object sender, System.EventArgs e)
{
   MatchCollection matches = Regex.Matches(SearchStringTextBox.Text, 
MatchExpressionTextBox.Text);
   MatchCountLabel.Text = matches.Count.ToString();
   MatchesLabel.Text = "";
   foreach(Match match in matches)
   {
      MatchesLabel.Text += "Found " + match.ToString() + " at 
position " + match.Index + ".<br>";
   }
}

기본 동작 외에 다른 동작을 지정해야 할 경우 일반적으로 Regex 클래스의 인스턴스를 인스턴스화해야 합니다. 특히 설정 옵션의 경우가 그렇습니다. 예를 들어 대/소문자와 패턴 공백을 무시하는 Regex 인스턴스를 만들고 해당 식에 대해 일치하는 항목 집합을 검색하려면 다음 코드를 사용합니다.

Regex re = new Regex(pattern, 
   RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
MatchCollection mc = re.Matches(inputString);

이 샘플의 전체 작업 버전은 다운로드한 이 기사에 단순 ASP.NET 페이지로 포함되어 있습니다.

무료 도구

Regulator(http://royo.is-a-geek.com/iserializable/regulator/ ) - 클라이언트 쪽에서 실행하도록 만들어진 정규식 테스트 도구로서, 웹 서비스를 통해 RegexLib과 통합되며 일치, 분할, 바꾸기 등을 지원합니다. 성능 분석 및 구문 강조가 포함됩니다.

RegexDesigner.NET(http://www.sellsbrothers.com/tools/ ) - 정규식을 구성하고 테스트할 수 있는 강력한 비주얼 도구입니다. C# 및/또는 VB.NET 코드 및 컴파일된 어셈블리를 생성하여 식을 응용 프로그램에 쉽게 통합할 수 있게 합니다.

Regular Expression Workbench v2.0(http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=C712F2DF-B026-4D58-8961-4EE2729D7322 ) - 정규식을 만들고 테스트하고 연구할 수 있는 Eric Gunnerson의 도구입니다. 마우스로 regex를 가리켜 그 의미를 디코딩할 수 있는 "Examine-o-matic" 기능이 들어 있습니다.

고급 항목

여기서 주목할 만한 두 가지의 정규식 기능은 명명된 그룹 및 둘러보기 처리(lookaround processing)입니다. 하지만 이 두 가지 항목은 자주 사용되는 것이 아니므로 여기서는 간략하게만 설명하겠습니다.

명명된 그룹을 사용할 경우 일치하는 개별 그룹에 이름을 지정하고 식 내에서 프로그래밍 방식으로 이러한 그룹을 참조할 수 있습니다. 입력 문자열에서 요소의 순서와 배치를 다시 정렬하여 입력 문자열의 서식을 바꿀 때 Replace 메서드와 함께 사용하면 특히 유용합니다. 예를 들어 MM/DD/YYYY 문자열 형식으로 지정된 날짜를 DD-MM-YYYY 형식으로 바꾸려는 경우를 가정해 봅니다. 첫 번째 형식을 캡처하고 해당 Matches 컬렉션을 반복한 다음 문자열 처리를 사용하는 식을 써서 바꾸기 문자열을 만들 수 있습니다. 이 식에는 어느 정도의 코드 및 처리가 필요합니다. 명명된 그룹을 사용하여 이와 같은 작업을 수행할 수 있습니다.

String MDYToDMY(String input)
{
   return Regex.Replace(intput, 
@"\b(?<month>\d{1,2})/(?<day>\d{1,2}/(?<year>\d{4})\b",
"${day}-${month}-${year}"); }

또한 이름뿐 아니라 번호로도 그룹을 참조할 수 있습니다. 모든 이벤트에서 이러한 참조를 역참조라고 합니다. 또한 일반적으로 역참조는 반복되는 문자를 찾기 위한 [a-z]\1 식과 같이 일치하는 식 자체 내에서 많이 사용됩니다. 이 식은 'aa', 'bb', 'cc' 등과는 일치하지만 'ab', 'ac' 등 모든 두 글자 조합에 해당하거나 이를 허용하는 [a-z]{2} 또는 [a-z][a-z]와는 다릅니다. 역참조를 사용하면 식에서 이미 구문 분석하고 일치시킨 입력 문자열의 일부에 대해 기억할 수 있습니다.

"둘러보기 처리"는 많은 정규식 엔진에서 지원하는 긍정적, 부정적 예측 및 분석 기능을 참조합니다. 모든 정규식 엔진에서 둘러보기 처리의 모든 변형을 지원하는 것은 아닙니다. 이 구성은 문자와 일치할 수 있지만 문자를 사용하지는 않습니다. 일부 패턴은 둘러보기 처리를 사용하지 않고 설명할 수 없습니다. 특히 패턴 일부의 존재가 다른 부분의 존재에 따라 결정되는 경우에는 더욱 그렇습니다. 각 둘러보기 기능의 구문은 다음과 같습니다.

구문 설명
(?=…) 긍정적 예측(Positive Lookahead)
(?!...) 부정적 예측(Negative Lookahead)
(?<=…) 긍정적 분석(Positive Lookbehind)
(?<!...) 부정적 분석(Negative Lookbehind)

둘러보기 처리를 사용해야 하는 경우의 예로는 암호 유효성 검사가 있습니다. 적어도 숫자가 하나 이상 포함된 4자에서 8자 사이의 암호를 입력해야 하는 암호 제한을 가정해 봅니다. 일치 항목에 대해 \d를 테스트하고 문자열 작업을 사용하여 길이를 테스트함으로써 이 작업을 수행할 수 있지만 정규식에서 전체를 수행하려면 둘러보기가 필요합니다. 다음 식이 나타내는 것과 같이 특히 긍정적 예측의 경우 더욱 그렇습니다. ^(?=.*\d).{4,8}$

결론

정규식을 사용하면 텍스트의 패턴을 효과적으로 설명할 수 있으므로 문자열 유효성 검사와 처리를 위한 리소스로 활용할 수 있습니다. .NET Framework는 System.Text.RegularExpressions 네임스페이스를 비롯하여, 특히 Regex 클래스에서 정규식을 완벽하게 지원합니다. API는 사용하기가 간편하지만 올바른 정규식을 사용하는 것이 때로는 어려운 일입니다. 다행히 정규식은 재사용률이 매우 높으며 많은 온라인 리소스에서 다른 사용자가 지정한 식을 찾아서 활용할 수도 있고, 만들기 어려운 정규식에 대해 도움도 받을 수 있습니다.

리소스

정규식 라이브러리 http://www.regexlib.com/ 

정규식 토론 목록 http://aspadvice.com/login.aspx?ReturnUrl=%2fSignUp%2flist.aspx%3fl%3d68%26c%3d16&l=68&c=16 

정규식 포럼 http://forums.regexadvice.com/ 

정규식 웹 로그 http://blogs.regexadvice.com/ 

Jeffrey Friedl의 Mastering Regular Expressions(O'Reilly) http://www.regex.info/ 

.NET 정규식 참조 http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemTextRegularExpressions.asp 

Jscript 정규식 구문 http://www.msdn.microsoft.com/library/en-us/script56/html/js56jsgrpRegExpSyntax.asp 

정규식 정보 http://www.regular-expressions.info/ 

저자 소개

Microsoft ASP.NET MVP인 Steven A. Smith는 ASPAlliance.com 및 DevAdvice.com의 사장이자 소유자입니다. 또한 .NET 중심 교육 기관인 ASPSmith Ltd의 소유자이자 대표 강사로, MSDN 및 AspNetPRO 잡지에 실리는 기사뿐 아니라 ASP.NET Developer's Cookbook과 ASP.NET By Example 두 권의 책을 저술한 바 있습니다. 또한 매년 열리는 여러 회의에서 강연을 맡고 있고 INETA 강연자 협회의 회원이며, 경영학 석사 및 컴퓨터 과학 기술 학사 학위를 소지하고 있습니다.

전자 메일(ssmith@aspalliance.com)을 통해 저자와 연락할 수 있습니다.

이 포스트를.. 수정 삭제

덧글 쓰기 엮인글 쓰기

웹개발 시 보안체크리스트 20 비공개 웹개발

2008/03/03 11:25 수정 삭제

복사 http://blog.naver.com/sobakcc/60048644209

http://blog.naver.com/imbyuri/110012839564

 

Guide 1. 세션유지를 위해서 Cookie를 사용할경우, 위/변조에 대비해야 한다.

■보안 수단없이 쿠키에 인증정보를 저장해서 사용할 경우 해당값들의 위,변조가 가능하며, 이로 인하여 다른 사용자로 위장 또는

  권한상승 등의 문제가 생길 수 있다. 따라서 쿠키를 사용할 경우, 쿠키값의 불법 위/변조가 불가능하도록 구현해야 한다.

 

■점검방법 : 사이트에 로그인한 후, 웹브라우저의 주소창에 javascript:document.cookie;  입력해서 내용을 확인한후,

   해당 세션 쿠키를 사용하는 웹어플리케이션 소스 점검을 통해 불법 변조탐지루틴이 있는지 확인한다.

 

■조치방법 : 아래 방법들 중에서 가능한 것을 선택해서 적용함.
1) 쿠키값 암호화를 통한 쿠키불법 변조방지(서버에서 전송받은 쿠키를 복호화 한후, 위/변조 되었는지 확인)
2) 쿠키값에 대한 Message Digest(예, MD5, SHA-1 등) 값의 첨부 및 검증을 통한위,변조탐지(아래예제참조)
3) 쿠키에 세션값을 저장하는 대신어플리케이션서버세션사용(사용하는웹어플리케이션서버가지원하는지확인필요)
<php 예제>
$secret_word = ‘lgcard_secret_value’;
// 쿠키설정하기
$id = ‘lgcard’;
$hash = md5($secret_word . $id);
setcookie('id', $id . '-‘. $hash);
// 받은 쿠키가 변조되었는지 확인하기
list($cookie_id,$cookie_hash) = explode('-',$_COOKIE['id']);
if (md5($secret_word.$cookie_id) == $cookie_hash) {
$id = $cookie_id;
} else {
  die('Invalid cookie !');
}
<asp 예제>
<!--#include virtual="/crypto/MD5.asp"-->
secret_word = “lgcard_secret_value”
// 쿠키설정하기
id = “lgcard”
hash = md5(secret_word & id);
Response.Cookie(“id”) = id
Response.Cookie(“id_hash”) = hash
// 받은쿠키가변조되었는지확인하기
cookie_id = Request.Cookie(“id”)
cookie_hash = Request.Cookie(“id_hash”)
If md5(secret_word & cookie_id) = cookie_hash) Then
   ‘Cookie 값이변조되지않았으므로, 세션ID 값설정
   id = cookie_id
Else
   ‘Cookie 값이 변조되었기 때문에, 오류처리
End
<jsp예제>
String secret_word = “lgcard_secret_value”;
// 쿠키설정하기
String id = “lgcard”;
String id_hash = CryptoUtil.md5(secret_word + id);
Cookie userCookie= new Cookie(“id”, id + “-”+ id_hash);
Response.addCookie(userCookie);
// 받은쿠키가변조되었는지확인하기
Cookie[] cookies = request.getCookies();
for(inti=0; i<cookies.length; i++) {
  Cookie thisCookie= cookies[i];
  if (thisCookie.getName().equals(“id”)) {
    String cookie_value = thisCookie.getValue();
    StringTokenizerst= new StringTokenzier(cookie_value, “-”);
    String cookie_id = st.nextToken();
    String cookie_hash = st.nextToken();
    if (CryptoUtil.md5(secret_word + cookie_id).equals(cookie_hash)) {
      id = cookie_id;
    } else {
      // Cookie 값이 변조되었기 때문에, 오류처리
    }
  }
   //다른쿠키에대한처리루틴
}
* 쿠키에대한 Hash 값을만들때, 공격자가 해당Hash 값을 불법으로 생성하는것을 막기위해서, 웹 사용자에게 공개 되지않는
secret_word 값을함께 사용한다. 이값은 해당웹어플리케이션에서 사용할수있도록 공용 설정파일등에 저장해서 사용하는것을 권장한다.
Guide 2. 접근제어가 필요한 모든 페이지에 로그인 체크 및 권한 체크를 구현하자.
■접근제어가 필요한 페이지 및 모듈들에는 모두 통제수단(로그인체크, 권한체크)이 적용되어야 한다. 
  특히, 하나의 프로세스가 여러 개의 페이지 또는 모듈로 이뤄져 있을때 권한 체크가 누락 되었을 경우, 설정된 접근권한을 우회해서
  트랜젝션을 실행할 수 있는 위험이 존재한다.
■점검방법: 소스리뷰
■조치방법
1) 접근권한이 필요한 모든페이지/모듈에 해당루틴 구현
2) 이를위해서 공통 모듈을 사용하는 것을 권장한다.
Guide 3. 첨부파일 업로드 기능을 통한 스크립트 업로드 및 실행을 금지하자.
■ 게시판 첨부파일 업로드, 사진 업로드 모듈등 사용자가 임의의 파일을 서버로 전송할 수 있는 기능을 이용해서 공격자가 작성한
   악의적인스크립트를 서버에 업로드한후, 이를 실행시킬 수 있다면 해당 서버에서 임의의 명령어실행, Web DB 불법접근및
   해당 Application Server와 신뢰관계를 맺고있는 서버들(예, Web DB서버, 내부 연동서버등)을 공격할 수 있는 위험이 있다.
  본 취약점은 게시판 업로드 모듈뿐아니라 그림 파일을 올리는 기능을 통해서도 발견되고 있기때문에, 사용자가 파일을 업로드할
  수 있는 모든 모듈에 적용된다.
■점검방법 : 해당Application Server가 지원하는 Script 파일을 업로드한 후, 이를 웹브라우저로 직접 접근해서 실행이 되는지
                 확인한다.
■조치방법
1) 해당 Application Server에서Script로 실행될 수 있는 확장자(예, .jsp, .asp, .php, .inc 등)로된 파일의 업로드를 차단한다.
2) 첨부파일을 웹디렉터리가 아닌 곳에 저장한후, 다운로드 스크립트를 사용해서 사용자에게 전달할 수 있게한다.
3) 다운로드 스크립트를 구성할때, 파일명을 Parameter로 받는것보다 파일이름은 DB에 저장하고 해당index만을 Parameter로
    받아서 사용하면 더 안전하다.
※주의사항
1) 확장자를 비교할경우, 대소문자를 무시한 문자열비교를 해야만한다. 이를 적용하지않으면 공격자는
   “malcious.Jsp ”,  “malicious.jSp ”,  “malicious.jsP ” 등과 같은 파일명을 사용해서 통제루틴을 우회할 수 있기 때문이다.
2) 웹어플리케이션 서버에서 실행 스크립트로 설정한 모든 확장자에 대해서 점검해야하며, 이들 확장자 목록은 웹 서버 관리자에게
   문의해서 확인해야 한다.
Guide 4. 첨부파일 다운로드스크립트를 악용한 서버파일유출을 방지하자.
■첨부파일 다운로드 스크립트에 파일 경로를 포함한 parameter를 사용할 경우, 원하는 디렉터리를 벋어나서 임의의 파일을 다운로드
  할수 있는 취약점이 있다. 이로 인하여 공격자는서버의 중요파일 또는 웹어플리케이션 소스파일등에 접근이 가능하다.
■점검방법: http://localhost/download.jsp ? file=lgsec.txt와같이 구현되어있는 웹 어플리케이션이 있다고하자.
1) Application Server가Unix/Linux인경우
    http://localhost/download.jsp ? file=../../../../../../../etc/passwd를 입력했을때 Application Server의 /etc/passwd 파일을
    획득할 수 없어야 한다.
2) Application Server가 Windows 계열인 경우
   http://localhost/download.asp ? file=../../../winnt/win.ini를 입력했을때 win.ini 파일을 획득할 수 없어야 한다. 
■조치방법 : 사용자로 부터 전송받은 디렉터리이름, 파일이름값에 “../ ” 또는 “..\ ”이 존재하면 오류처리 한다. 
Guide 5. SQL Injection 공격에 대비하자.
■사용자로 부터 입력 받은값을 DB query에 사용할 경우, 공격자는 원하는query 문을 injection할 수 있는 취약점이 있다.
  로그인 모듈이 SQL Injection에 취약할 경우, 사용자의 비밀번호를 몰라도 정상적으로 로그인할 수 있는 위험이 있으며, 게시판 등의
  모듈이 취약할 경우 DB 내용이 외부로 유출 또는 임의의 DB Query가 실행될 수 있다.
■원리
ID, PASSWORD를 받아서 로그인 성공 여부를 처리하는 예를 들어보자.
id = request(“id”);
passwd= request(“passwd”);
query = “select * from MEMBER where id = ‘” + id + “’ and passwd= ‘” + passwd+ “’”;
로 되어있어서 결과Record가 있을 경우 회원 로그인 성공처리하는 경우, Id에 ‘ or 1=1 –- 입력할 경우 비밀번호에 상관없이
다음과 같은query가 만들어진다. (여기서passwd가123으로 입력되었다고 하자)
Select * from MEMBER where id = ‘ ’ or 1=1 –-‘ and passwd=  ‘123 ’
Oracle DB에서 –- 부분은 주석으로 처리되기 때문에 위 쿼리의 결과는 항상 첫 번째 레코드가 반환되며, 단순하게 레코드 반환 여부만을
점검 하는식으로 인증이 구현되어 있다면, 로그인이 성공적으로 처리되게 된다. 이를 응용하면 원하는 사용자ID로 로그인이 가능할 수
도 있다.
또한 이와같은 원리를 사용해서 사용자 입력값의 조작으로 임의의 DB Query를 실행시킬 수 있는 위험이 존재한다.
■점검방법: 
1) 검색어 필드 및 로그인ID, PASSWD  필드에 큰따옴표(“), 작은따옴표( ‘), 세미콜론(;) 등을 입력한후, DB error가 일어나는지
   확인하자.
2) 로그인모듈점검
A. MS SQL인 경우: ID 필드에[ ‘ or 1=1 ;--], 비밀번호필드에는 아무값이나 입력한 후 로그인을 시도한다.
B. Oracle인 경우: ID 필드에[ ‘ or 1=1 --], 비밀번호 필드에는 아무값이나 입력한 후 로그인을 시도한다.
C. 기타: ID 필드에[‘ or ‘’=‘], 비밀번호필드에[‘ or  ‘’=‘]을 입력한후 로그인을 시도한다.
* 위예제이외에도다양한방법이가능하기때문에, 로그인및사용자입력값을사용하는소스에서DB Query 생성방식을직접
점검해야한다.
■조치방법
1) 사용자로부터 입력 받은값에 큰따옴표(“), 작은따옴표( ‘), 세미콜론(;) 문자가있으면 이를제거 또는 사용하는 DB에 맞게 변환
한후, DB query문장에 사용하도록한다.
Guide 6. Cross-Site Scripting 공격에대비하자.
■사용자가 입력한 내용을 기반으로 페이지를 동적으로 생성하는 웹어플리케이션을 악용하면, 해당페이지를 보는 사용자의
웹브라우저에서 임의의코드를 실행할 수 있다. 이는 로그인세션 hijacking, 악성 프로그램설치등의 client hacking이 가능하다.
■점검방법: 게시판의제목, 내용 필드등에 <script>alert( “XSS 취약함 ”);</script> 입력한후, 내용을조회했을때, 해당스크립트가
실행되면 취약하다.
■점검방법: 게시판의 제목, 내용 필드등에 <script>alert( “XSS 취약함 ”);</script> 입력한 후, 내용을 조회했을때, 해당스크립트가
실행되면 취약하다.
■조치방법: 사용자로부터 입력받은 내용을 기반으로 페이지를 생성할경우, “<“,  “> ”는각각“&lt; ”,  “&gt; ”로 변경한 후 생성한다.
1) PHP의경우, htmlspecialchars() 함수를 사용해서입력받은값을변환할수있다. 
2) Java 1.4 API 이상
content = content.replaceAll("<",  “&lt;");  // 사용자가입력한내용이content 변수(String 객체)에저장되어있다고가정
content = content.replaceAll(">",  “&gt;");
3) Java 1.3 API 이하
intlocation;
do {
  location = content.indexOf('<');
  if (location > 0) content = content.substring(0, location) +  “&lt;" + content.substring(location+ 1);
  location = content.indexOf('>');
  if (location > 0) content = content.substring(0, location) +  “&gt;" + content.substring(location+ 1);
} while(content.indexOf('<') != -1 || content.indexOf('>') != -1);     
* 주의사항 만약 HTML Tag의 입력을 허용하는 모듈일경우, 위의변환규칙대신<script, </script>, <iframe>을 각각<!--script, </script--!>, <! —iframe> 
으로 변경하며, 이때 대소문자를 무시한 패턴매칭 (Java의경우String 클래스의toLowerCase()  및 substring() 사용)을 적용해야만 한다.
Guide 7. 사용자에게 전달된값(HIDDEN form 필드, parameter)을 재사용할경우 신뢰해서는 안된다.
■주로 회원정보변경 모듈에 사용자의 key값(예, id)를 hidden form 필드로 전송한 후, 이를 다시받아서 update에 사용하는 경우가
  있는데, 공격자가 이값을 변경할경우 다른 사용자의 정보를 변경할 수 있는 취약점이 존재한다.
■점검방법: HTML 소스에서 FORM 필드 확인 후, 해당값이 어떻게 사용되는지를 소스에서 확인해야 한다.
■조치방법: 해당값의 무결성을 검사 할수있는루틴(예, 해쉬값비교) 추가 또는 서버세션을 사용한다.`
Guide 8. 최종 통제메커니즘은 반드시 서버에서 수행 되어야한다. (Client-Site Security is NOT secure!!)
■JavaScript, VBScript 등을 사용한 사용자 입력값 점검루틴은 우회될 수 있기때문에, 서버에서 최종 점검하는것이 필요하다.
물론 서버의 부하를 줄이기위해서 1차적으로 클라이언트 레벨에서 점검할 수 있으나, 보안 통제수단으로 사용할 수 없다.
첨부파일 업로드 기능에 스크립트 파일의 전송제한하기 위해서 파일확장자검사를 script를 사용해서 웹브라우저 레벨에서
수행할 경우, 공격자는 해당script를 우회해서 서버에 원하는 스크립트파일을 전송할 수 있다.
■점검방법: HTML 및 웹어플리케이션 소스리뷰
Guide 9. 클라이언트에게 중요정보를 전달하지말자.
■Java Applet, ActiveX를 사용해서 C/S 어플리케이션을 작성하는경우, 클라이언트에서 실행되는 컴포넌트에 중요정보를 하드코딩
해서는 안된다. Cookie에중요정보를 전달할경우, 암호화를 사용해야 한다.
■점검방법
1) HTML 소스리뷰
2) URL 주소에javascript:document.cookie; 입력해서 쿠키내용 확인
Guide 10. 중요정보전송시POST method 및 SSL을 적용해야한다.
■사용자로부터 중요정보를 받을때는 POST method를 사용해야하며, 그 중요도에 따라 SSL을 사용한 암호화통신을 적용해야한다.
SSL은 자료전송시 암호화를 지원하므로, 민감한정보는 어플리케이션 레벨의 암호화를 고려해야한다.
■점검방법: 중요정보전달 FORM ACTION에 사용된 프로토콜이 “HTTPS”, Xecure로 되어있는지 확인함
Guide 11. 중요한 트렌젝션이 일어나는 프로세스에 사용자의 비밀번호를 재확인 하도록 하자.
■사용자의개인정보변경프로세스에비밀번호를재확인하는루틴을추가할경우불법적인위장으로인한추가피해를줄일수있다.
■점검방법: 해당프로세스확인
Guide 12. 중요정보를 보여주는 페이지는 캐쉬를 못하게 설정하자.
■중요정보를 보여주는 화면에 no-cache 설정을 하지않을경우, 로그아웃을한 이후에도 [뒤로가기] 버튼을 사용해서 해당내용을
볼 수 있는 위험이 존재한다.
■점검방법: 중요 정보페이지를 열어본 후, 로그아웃을 한다. 웹브라우저의 “뒤로”버튼을 눌렀을때 이전내용이 보이는지 확인.
■조치방법: no-cache 설정을위해서HTML HEAD 부분에 아래내용을 추가한다.
<meta HTTP-EQUIV=“Pragma”CONTENT=“no-cache”>
Guide 13. 암호화를 올바르게 이해하고 사용하자.
■자체개발한 암호화 알고리즘 사용을지양하며, 공인된 암호화알고리즘(3DES, SEED, AES 등)을 사용하는것을 고려한다.
암호화키를 사용하지 않는 알고리즘은 암호화알고리즘이 아니라, 단순인코딩 알고리즘으로 기밀성을 보장할 수 없다.
암호화키는 소스에 hard-coding되어서는 안되며, 제한된 사람만이 접근이 가능하도록 해야한다.
Guide 14. 관리자 페이지는 내부에서만 접근이 가능하도록 하자.
■웹 사이트관리자를  위한  페이지가 존재할경우, 외부에서 접근이불필요하다면 내부특정IP에서만 접근할 수 있도록 통제해야한다.
■이를위해서 특정Directory에 관리자페이지들을 구성하고, 해당Directory에 접근제한을 적용한다.
■조치방법: Apache Web Server를 사용하는경우 httpd.conf에 아래내용을추가하면된다.
(관리자페이지가/lgsec/admin 아래저장되어있고, 관리자IP가192.168.0.101 인경우)
<Directory “/lgsec/admin”>
Deny from all
Allow from 192.168.0.101
</Directory>
Guide 15. 각언어에서 제공하는 보안수단을 이해한후 사용한다.
■Java
1) Java Class 역컴파일문제
Java 언어의Byte-code 특성으로 인하여Java class는 쉽게역컴파일이가능하다. 만약Java Applet에 중요정보(예, 원격지접속
을 위한ID/PASSWORD, DB Query, 직접제작한 암호화알고리즘, 프로그램로직 등) 를hard-coding 했다면, 이를 발견한공격자
는 해당정보를 악용할 수 있는위험이 존재한다. 따라서 외부로 전송되는 Java class 파일에는 중요정보를 hard-coding하는것을
지양해야 한다.
2) Secure Code guidelines (Sun Microsystems) -http://www.java.sun.com/security/seccodeguide.html
Sun Microsystems에서는Java 프로그램 개발시고려해야할 다양한 보안사항을 제공하고있다.
■ASP(Visual Basic, C++, C# 등을사용한모든ASP에적용)
1) include 파일을보호하자
2) Server.HTMLEncode
-용도: 특정문자열에 대한 HTML  encoding을 수행한다. 사용자가 입력한값으로 HTML 페이지를 구성하기전에 사용하면
Cross-Site Scripting 공격등에 효과적이다.
-적용가능한IIS : IIS 5.0 이상
-사용법
<%= Server.HTMLEncode(“<script>alert(document.cookie);</script>”) %>
-결과
&lt;script&gt;alert(document.cookie); &lt;/script&gt;
3) Server.URLEncode
4) Session.Abandon
-용도: Session 객체에 저장되어 있는 모든 정보를 삭제한다. 사용자 로그아웃 프로세스에 사용해서 기존세션정보를
보호하기위해서 사용할 수 있다.
-적용가능한IIS : IIS 5.0 이상
-사용법
<% Session.Abandon %>
■PHP
1) [PHP 4 이상] 환경설정(php.ini) 내용중register_global을 “on”으로 설정할 경우, PHP 스크립트의 변수값을 임의로 변경할 수
있는 취약성이 있다. 따라서 register_global은“off”로 설정한 후, $_GET, $_POST 문을 사용해서 사용자가 전달한값을 얻어야
한다.
register_global = off
2) PHP 스크립트오류를 사용자에게 보내지 않기 위해서 PHP 환경설정파일(php.ini)에서 아래와 같이설정한다.
log_errors = On
display_errors = Off
3) utf8_decode()
-용도: UTF-8 형식의입력값을ISO-8859-1 형식으로전환해준다. 필터링규칙을적용하기전에사용할것을권장한다.
-적용가능한PHP : PHP 3.0.6 이상
4) strip_tags()
-용도: 문자열로부터HTML 테그와PHP 테그를없앤다. 사용자가입력한값을HTML 화면에출력할경우사용해서
Cross-Site Scripting 공격을 대비할 수 있다.
-적용가능한PHP : PHP 3.0.8 이상
-사용법
A. strip_tags(‘<script>’); : 모든HTLL, PHP 테그를제거한다.
B. strip_tags(‘<script>’, ‘<script><iframe>’) : 첫번째인자로전달된문자열에서두번째인자로지정된테그를제거한다.
5) htmlspecialchars()
-용도: 특정문자열에 대한 HTML encoding을 수행한다. 사용자가 입력한값으로 HTML 페이지를 구성하기전에 사용하면
Cross-Site Scripting 공격대비를위해서사용할수있다.
-적용가능한PHP : PHP 3 이상
-사용법
htmlspecialchars(“<a href=‘test’>Test</a>”)
-결과
&lt;ahref=‘test’&gt;Test&lt;/a&gt;
6) addslashes()
-용도: DB Query와같이인용된부분앞에역슬래쉬를붙여서반환한다. 해당문자에는작은따옴표, 큰따옴표, 역슬래쉬,
NULL 이있다. SQL Injection 공격을위해서사용한다.
-적용가능한PHP : PHP 3 이상
7) include 파일을보호하자.
8) session_destroy
-용도: Session 객체에 저장되어있는 모든정보를 삭제한다. 사용자 로그아웃프로세스에 사용해서 기존세션정보를
보호하기 위해서 사용할 수 있다.
-적용가능한PHP : PHP 4 이상
Guide 16. 슈퍼 유저 계정을 사용한 코딩 금지
반드시 필요한 경우가 아니면 관리자 및 슈퍼 유저 계정을 사용하여 코딩을 하여서는 안 되며 개발 초기 단계에서 개발하고자 하는
어플리케이션에 특화된 계정을 사용하여 개발하여야 한다. 예를 들어 SQL 서버에 접속하는 어플리케이션일 경우 ‘sa’ 계정보다는
새로운 사용자 계정을 생성하여 개발하여야 한다.
Guide 17. 버퍼 오버플로우
대부분의 보안 취약점은 버퍼오버플로우 문제로 인해 발생한다. 버퍼오버플로우는 고정된 길이의 버퍼에 값을 쓸 때 버퍼의 경계값을 넘어서면서
발생하게 되는데 사용자 입력 값을 읽을 때나 프로그램 내에서 처리하는 중간에 발생한다. C언어와 C++언어는 버퍼오버플로우에 대한 보호기능을
제공하지 않으므로 CGI 프로그램을 작성할 때 아래의 사항들을 준수하여야 한다.
- strcpy(), strcat(), sprintf(), vsprintf(), gets()와 같은 함수는 경계값을 체크하지 않으므로 strncpy(), strncat(), snprintf(), fget()과 같은 함수로 대체하여야 한다.
- realpath(), getopt(), getpass(), streadd()와 같은 함수의 사용은 자제하고 최소한의 PATH_MAX 바이트 길이를 정해주는 getwd() 함수를 사용하도록 한다.
- scanf(), sscanf(), fscanf() 함수 사용시에는 읽어들일 수 있는 최고의 버퍼 길이를 명시해야 한다.
¤ 취약한 사용 예
char buffer[256];
int num;
num = fscanf( stdio, “%s”, buffer );
¤ 안전한 사용 예
char buffer[256];
int num;
num = fscanf( stdio, “%255s”, buffer );
- memcpy() 함수를 사용할 경우에는 복사할 대상의 크기를 체크하여야 한다.
¤ 취약한 사용 예
unsigned long copyaddress( struct hosten *hp )
{
unsigned long address;
memcpy( &address, hp->h_addr_list[0], hp->h_length );
}
¤ 안전한 사용 예
unsigned long copyaddress( struct hosten *hp )
{
unsigned long address;
if ( hp->h_length > sizeof( address ) )
return 0;
memcpy( &address, hp->h_addr_list[0], hp->h_length );
return address;
}
반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


C# 프로그래머 참조  

문서 주석에 대한 권장 태그

http://msdn.microsoft.com/library/kor/default.asp?url=/library/kor/csref/html/vclrftagsfordocumentationcomments.asp

 

C# 컴파일러는 코드의 문서 주석을 XML 파일로 만듭니다. XML 파일을 처리하여 문서를 만드는 작업은 사용자의 사이트에서 구현해야 하는 세부적인 사항입니다.

태그는 형식, 형식 멤버 등과 같은 코드 구문에서 처리됩니다.

참고   태그는 네임스페이스에서 처리되지 않습니다.

컴파일러는 유효한 XML 태그를 모두 처리합니다. 아래 태그에는 사용자 문서에서 자주 사용하는 기능이 포함되어 있습니다.

1. 컴파일러는 구문을 검증합니다.

참고 항목

/doc(문서 주석 처리) | XML 문서

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


C# 프로그래머 참조  

<c>

<c>text</c>

다음은 각 문자에 대한 설명입니다.

text
코드로 나타낼 텍스트입니다.

설명

<c> 태그는 설명에 있는 텍스트를 코드로 표시하는 데 사용합니다. 여러 줄을 코드로 표시하려면 <code>를 사용합니다.

/doc로 컴파일하여 문서 주석을 파일로 저장합니다.

예제

// xml_c_tag.cs
// compile with: /doc:xml_c_tag.xml

/// text for class MyClass
public class MyClass 
{
   /// <summary><c>MyMethod</c> is a method in the <c>MyClass</c> class.
   /// </summary>
   public static void MyMethod(int Int1) 
   {
   }
   /// text for Main
   public static void Main () 
   {
   }
}

참고 항목

문서 주석에 대한 권장 태그

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


C# 프로그래머 참조  

<code>

<code>content</code>

다음은 각 문자에 대한 설명입니다.

content
코드로 표시할 텍스트입니다.

설명

<code> 태그는 여러 줄을 코드로 표시하는 데 사용합니다. <c> 태그는 설명에 있는 텍스트를 코드로 표시하는 데 사용합니다.

/doc로 컴파일하여 문서 주석을 파일로 저장합니다.

예제

<code> 태그의 사용 방법을 보여 주는 예제는 <example> 항목을 참조하십시오.

참고 항목

문서 주석에 대한 권장 태그

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


C# 프로그래머 참조  

<example>

<example>description</example>

다음은 각 문자에 대한 설명입니다.

description
코드 예제에 대한 설명입니다.

설명

<example> 태그를 사용하면 메서드나 기타 라이브러리 멤버의 사용 방법에 대한 예제를 지정할 수 있습니다. 대개 이 태그는 <code> 태그와 함께 사용합니다.

/doc로 컴파일하여 문서 주석을 파일로 저장합니다.

예제

// xml_example_tag.cs
// compile with: /doc:xml_ctag.xml

/// text for class MyClass
public class MyClass 
{
   /// <summary>
   /// The GetZero method.
   /// </summary>
   /// <example> This sample shows how to call the GetZero method.
   /// <code>
   ///   class MyClass 
   ///   {
   ///      public static int Main() 
   ///      {
   ///         return GetZero();
   ///      }
   ///   }
   /// </code>
   /// </example>
   public static int GetZero() 
   {
      return 0;
   }
   /// text for Main
   public static void Main () 
   {
   }
}

참고 항목

문서 주석에 대한 권장 태그

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


C# 프로그래머 참조  

<exception>

<exception cref="member">description</exception>

다음은 각 문자에 대한 설명입니다.

cref = "member"
현재 컴파일 환경에 있는 예외에 대한 참조. 컴파일러에서는 지정된 예외가 존재하는지를 확인하고 member를 출력 XML의 정식 요소 이름으로 변환합니다. member는 큰따옴표(" ")로 묶어야 합니다.
description
설명.

설명

throw할 수 있는 예외를 <exception> 태그에 지정합니다. 이 태그는 메서드 정의에 적용됩니다.

/doc로 컴파일하여 문서 주석을 파일로 저장합니다.

예제

// xml_exception_tag.cs
// compile with: /doc:xml_exception_tag.xml
using System;

/// comment for class
public class EClass : Exception 
{
   // class definition ...
}

/// <exception cref="System.Exception">Thrown when... .</exception>
class TestClass 
{
   public static void Main() 
   {
      try 
      {
      }
      catch(EClass) 
      {
      }
   }
}

참고 항목

문서 주석에 대한 권장 태그

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


C# 프로그래머 참조  

<include>

<include file='filename' path='tagpath[@name="id"]' />

다음은 각 문자에 대한 설명입니다.

filename
문서를 포함할 파일 이름입니다. 파일 이름은 path로 한정될 수 있습니다. filename은 작은따옴표(' ')로 묶습니다.
tagpath
태그의 name을 찾을 수 있는 filename의 태그 경로입니다. path는 작은따옴표(' ')로 묶습니다.
name
주석 앞에 오는 태그의 이름 지정자입니다. name에는 id가 있어야 합니다.
id
주석 앞에 오는 태그의 ID입니다. ID는 큰따옴표(" ")로 묶습니다.

설명

<include> 태그를 사용하면 소스 코드의 형식과 멤버를 설명하는 다른 파일의 주석을 참조할 수 있습니다. 이렇게 하면 소스 코드 파일에 직접 문서 주석을 배치하지 않아도 됩니다.

<include> 태그는 XML XPath 구문을 사용합니다. <include>의 용도를 변경하는 방법은 XPath 문서를 참조하십시오.

예제

아래 예제는 여러 개의 파일로 구성됩니다. <include>를 사용하는 첫째 파일은 아래와 같습니다.

// xml_include_tag.cs
// compile with: /doc:xml_include_tag.xml
/// <include file='xml_include_tag.doc' path='MyDocs/MyMembers[@name="test"]/*' />
class Test
{
   public static void Main()
   {
   }
}

/// <include file='xml_include_tag.doc' path='MyDocs/MyMembers[@name="test2"]/*' />
class Test2
{
   public void Test()
   {
   }
}

두 번째 파일 xml_include_tag.doc에는 다음 문서 주석이 있습니다.

<MyDocs>

<MyMembers name="test">
<summary>
The summary for this type.
</summary>
</MyMembers>

<MyMembers name="test2">
<summary>
The summary for this other type.
</summary>
</MyMembers>

</MyDocs>

프로그램 출력

<?xml version="1.0"?>
<doc>
    <assembly>
        <name>t2</name>
    </assembly>
    <members>
        <member name="T:Test">
            <summary>
The summary for this type.
</summary>
        </member>
        <member name="T:Test2">
            <summary>
The summary for this other type.
</summary>
        </member>
    </members>
</doc>

참고 항목

문서 주석에 대한 권장 태그

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요


C# 프로그래머 참조  

<list>

<list type="bullet" | "number" | "table">
   <listheader>
      <term>term</term>
      <description>description</description>
   </listheader>
   <item>
      <term>term</term>
      <description>description</description>
   </item>
</list>

다음은 각 문자에 대한 설명입니다.

term
text로 정의할 용어입니다.
description
글머리 목록이나 번호 매기기의 항목 또는 term의 정의입니다.

설명

<listheader> 블록은 테이블이나 정의 목록의 머리글 행을 정의하는 데 사용됩니다. 테이블을 정의할 때는 머리글의 term에 대한 엔트리만 제공하면 됩니다.

목록의 각 항목은 <item> 블록으로 지정합니다. 정의 목록을 만들 때는 termtext를 모두 지정해야 합니다. 그러나 테이블, 글머리 목록 또는 번호 매기기의 경우에는 text의 엔트리만 제공하면 됩니다.

목록이나 테이블에 사용할 수 있는 <item> 블록의 수에는 제한이 없습니다.

/doc로 컴파일하여 문서 주석을 파일로 저장합니다.

예제

// xml_list_tag.cs
// compile with: /doc:xml_list_tag.xml 

/// text for class MyClass
public class MyClass 
{
   /// <remarks>Here is an example of a bulleted list:
   /// <list type="bullet">
   /// <item>
   /// <description>Item 1.</description>
   /// </item>
   /// <item>
   /// <description>Item 2.</description>
   /// </item>
   /// </list>
   /// </remarks>
   public static void Main ()
   {
   }
}

참고 항목

문서 주석에 대한 권장 태그

반응형
Posted by 사용자 SB패밀리

댓글을 달아 주세요