현재 오프라인 상태입니다. 인터넷에 다시 연결하기를 기다리고 있습니다.

C# 기초로 한글 검색기(초성 포함) 만들기 [Step by Step]

저자 소개
이 문서는 박준백 MVP에 의해 작성되었습니다. 박준백 MVP가 운영하는 블로그를 통해 Microsoft 제품에 대한 지식과 정보를 공유하시기 바랍니다.
Microsoft MVP(Most Valuable Professionals)는 엄선된 최고의 기술 전문가들로서, 커뮤니티에서 적극적인 활동을 통해 다른 사용자들을 돕는 전문가로 구성된 그룹입니다.

소개
C#에서 기본적으로 제공하는 AutoComplete(자동 완성)에서는 한글 초성 검색이 안 되는 아쉬움이 있습니다. 현재 인터넷 검색 엔진에서 제공하는 AutoComplete(자동 완성)은 초성 뿐만 아니라 상당한 편의성의 자동 완성 컨트롤을 제공합니다. 이렇게 편한 컨트롤을 사용하는 사람들에겐 C# AutoComplete은 약간의 아쉬움을 남게 하여, 이 부분에 대해 간단한 프로그래밍 방법에 대해 설명을 합니다.


방법1: 문자 코드에 대하여
  1. 한글은 초성, 중성, 종성으로 나눠집니다. 
    -초성: ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ (19가지)
    -중성: ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ (21가지)
    -종성 : 없음, ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ (28가지)
  2. 완성된 글자를 만드는 순서는 아래와 같습니다.

    초성)ㄱ + 중성) ㅏ + 종성) 28개 ->

    초성)ㄱ + 중성) 중성 21개 + 종성) 28개 ->

    초성)19개 + 중성) 중성 21개 + 종성) 28개

    e.g) 가 -> 각 -> 갂 -> 갃….깨 -> 객 -> 갞 ….깋….힣
  3. '가’의 문자코드는 44032로 시작을 하며 587을 더하면 ‘ㄱ’의 마지막 문자인 ‘깋’이 나옵니다(588을 더하면 다음 초성이 나옵니다).
  4. 아래는 간단한 코드 샘플입니다
     class Program    {        static void Main(string[] args)        {            int x = 44032;             for (int i = 1; i <= 21; i++)            {                                for (int j = 1; j <= 28; j++)                {                    Console.Write("{0} : {1}", x, (char)x);                    x++;                }                Console.WriteLine();                                                        }        }    }

    출력 결과 




방법2: Regex 검색 패턴 만들기
  1.  '방법 1'에서 기초를 다뤘으니 이제는 약간 더 응용을 해서 'ㄱ수'를 입력했을때와 '가수'를 입력했을 때에 대하여 생각을 해야 합니다.

    - 초성만 입력했을 경우 chr 변수의 인덱스를 찾아 str 변수의 인덱스로 교체

    e.g) 'ㄱ'을 입력했을 때에는 가로 변환 후 출력 

     '가'를 입력했을 때에는 가를 출력
    char[] chr = { 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ',                           'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ','ㅋ','ㅌ', 'ㅍ', 'ㅎ' };          string[] str = { "가", "까", "나", "다", "따", "라", "마", "바", "빠", "사", "싸",                           "아", "자", "짜", "차","카","타", "파", "하" };string x = Console.ReadLine();string temp = "";            for (int i = 0; i < x.Length; i++)            {                if (x[i] < (char)43032)                {                    for (int j = 0; j < chr.Length; j++)                    {                        if (x[i] == chr[j])                        {                            temp += str[j];                        }                    }                }                else                {                    temp += x[i];                }            }             Console.WriteLine(temp);

    결과 화면 :입력을 하면 중성을 붙혀줍니다.


  2. 이제 Regex검색을 위한 패턴을 만들어야 합니다.

    - 'ㄱ'을 입력하면 ㄱ-깋까지 검색을 해야 합니다.

    - '가'를 입력하면 초성이 아니기 때문에 그대로 '가'를 temp에 넣습니다.
    int[] chrint = {44032,44620,45208,45796,46384,46972,47560,48148,48736,49324,49912,                               50500,51088,51676,52264,52852,53440,54028,54616,55204}; string x = Console.ReadLine();            string temp = "";            for (int i = 0; i < x.Length; i++)            {                if (x[i] < '가')                 {                    for (int j = 0; j < chr.Length; j++)                    {                        if (x[i] == chr[j])                        {                            temp += "[" + x[j] + "-" + (char)(chrint[j + 1] - 1) + "]";                        }                    }                }                else                {                    temp += x[i];                }            }

  3. 이제 간단한 linq와 regex문을 이용해서 검색을 한 후 출력을 합니다.
     var query = list.Where(e => Regex.IsMatch(e.ToString(),temp));             foreach (var c in query)            {                Console.WriteLine(c);            }    


방법3: 자동 완성 실행해 보기
  1. 전체 소스
     using System;using System.Collections.Generic;using System.Linq;using System.Text.RegularExpressions; namespace searchHan{    class Program    {         static void Main(string[] args)        {            char[] chr = { 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ',                           'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ','ㅋ','ㅌ', 'ㅍ', 'ㅎ' };             string[] str = { "가", "까", "나", "다", "따", "라", "마", "바", "빠", "사", "싸",                           "아", "자", "짜", "차","카","타", "파", "하" };             int[] chrint = {44032,44620,45208,45796,46384,46972,47560,48148,48736,49324,49912,                               50500,51088,51676,52264,52852,53440,54028,54616,55204};              List<string> list = new List<string>();            list.AddRange(new List<string> { "가시나무", "소나무", "목련", "백일홍", "청단풍", "홍단풍","가이즈까향나무","감나무","개나리","금송"});            string x = Console.ReadLine();            string pattern = "";            for (int i = 0; i < x.Length; i++)            {                if (x[i] >= 'ㄱ' &&  x[i] < '가')                {                    for (int j = 0; j < chr.Length; j++)                    {                        if (x[i] == chr[j])                        {                            pattern += "[" + str[j] + "-" + (char)(chrint[j + 1] - 1) + "]";                            //pattern += string.Format("[{0}-{1}]", str[j], (char)(chrint[j + 1] - 1));                        }                    }                }                else                {                    pattern += x[i];                }                           }            var res = list.Where(e => Regex.IsMatch(e.ToString(),pattern));             foreach (var c in res)            {                Console.WriteLine(c);            }             Console.WriteLine(pattern);        }    }}
    출력 화면
  2. C# 기초 문법에 약간의 Linq + Regex만으로 초성 검색에 대하여 간단히 다뤄봤습니다. 약간의 조건문만 더 추가하시면 좋을 것이라 생각됩니다. 약간의 코드를 더해보았습니다. 
    for (int i = 0; i < x.Length; i++)            {                //초성만 입력되었을때                if (x[i] >= 'ㄱ' && x[i] <= 'ㅎ')                {                    for (int j = 0; j < chr.Length; j++)                    {                        if (x[i] == chr[j])                        {                                                        pattern += string.Format("[{0}-{1}]", str[j], (char)(chrint[j + 1] - 1));                        }                    }                }                //완성된 문자를 입력했을때 검색패턴 쓰기                else if(x[i] >= '가')                                {                    //받침이 있는지 검사                    int magic = ((x[i] - '가') % 588);                     //받침이 없을때.                    if (magic == 0)                     {                        pattern += string.Format("[{0}-{1}]", x[i], (char)(x[i] + 27));                    }                                        //받침이 있을때                    else                    {                        magic = 27 - (magic % 28);                        pattern += string.Format("[{0}-{1}]", x[i], (char)(x[i] + magic));                    }                }                //영어를 입력했을때                else if (x[i] >= 'A' && x[i] <= 'z')                {                    pattern += x[i];                }                                //숫자를 입력했을때.                else if( x[i] >= '0' && x[i] <= '9')                {                    pattern += x[i];                 }            }     
추가 정보 
사용자 계정 컨트롤 메시지가 나타나면 관리자 암호를 입력하거나 [예]를 클릭합니다.
의견 보내기

Microsoft 고객지원 사이트에서는 고객님의 소리를 귀담아 듣습니다. 아래 의견 보내기로 소중한 의견 보내주시기 바랍니다.

커뮤니티 솔루션 고지 사항
Microsoft Corporation 및/또는 그 공급자는 어떤 목적으로든 여기에 있는 정보 및 관련 그래픽의 적합성, 안정성 또는 정확성에 대해 어떠한 보증도 하지 않습니다. 이러한 모든 정보 및 관련 그래픽은 어떠한 종류의 보증도 없이 "있는 그대로" 제공됩니다. Microsoft 및/또는 그 공급자는 상품성, 특정 목적에 대한 적합성, 전문적 노력, 제품명 및 비침해에 대한 모든 묵시적인 보증을 포함하여 본 정보 및 관련 그래픽에 대한 모든 보증을 배제합니다. Microsoft 및/또는 그 공급자는 어떠한 경우에도 여기에 포함된 정보 및 관련 그래픽의 사용 또는 사용할 수 없음으로 인해 발생하는 모든 직접적, 간접적, 징벌적, 부수적, 특별 손해 또는 기타 모든 손해(사용, 데이터 또는 이익 손실 등 기타 모든 손실을 포함하되 이에 제한되지 않음)가 계약, 불법 행위, 과실, 책무에 의한 것이든 책임을 지지 않으며 이는 Microsoft 또는 공급자가 그와 같은 손해의 가능성을 사전에 알고 있던 경우에도 마찬가지라는 데 동의합니다.
속성

문서 ID: 2701840 - 마지막 검토: 06/01/2012 06:57:00 - 수정: 1.1

Microsoft Visual C# 2010 Express

  • kbstepbystep kbmvp kbcommunity KB2701840
피드백
/html>>ript> yle="display: none; " src="https://c1.microsoft.com/c.gif?DI=4050&did=1&t=">;did=1&t=">