통합검색
· 마을서비스란?  · 포럼마을  · 일반마을  · 테마마을  · 마을랭킹  · 활동왕
· 덱스퍼트란?  · TECBOX   · PRSBOX   · 이용안내  
· DEXT제품군  · 솔루션베이  · S/W & ESD 컴포넌트
· 프로그램베이
· LiveSeminar  · LiveConference
데브피아 C# 포럼 마을에 오신 것을 환영합니다.
  마을등급 C#   이 마을은 포럼마을 입니다이 마을은 자유가입제 마을 입니다 마을소개 페이지로 이동 전입신청
마을촌장촌장 비사모 주민 12913 since 2006-12-28
우리마을 공지사항
질문&답변
강좌&팁
자유게시판
자료실
앨범
개인게시판
[마을 게시판]
구인/구직 게시판
건의 / 운영 제안
랑데브 게시판
칼럼 게시판
개발자 고충상담
Dev Talk
자유토론방
벼룩시장
재나미 우스개
구인/프로젝트 정보
사람인 채용 게시판
  고객지원 게시판
마이 데브피아
 나의 e-Money 내역
 활동왕 My Page
 스크랩한 게시글보기
 쪽지관리
 주소록관리

 강좌&팁
 [강좌] C#을 이용한 자연어 처리(3)  | Other 2006-08-20 오후 6:01:29
 inobae  inobae님께 메시지 보내기inobae님을 내 주소록에 추가합니다.inobae님의 개인게시판 가기 번호: 1171  / 읽음:14,487

 3.    유니코드를 이용한 한글 자모 분리와 결합

 

3.1 한글 유니코드

유니코드에도 많은 종류가 있지만, 우선 유니코드 중 가장 많이 사용되는 유니코드는 UTF-8 UTF-16정도로 볼 수 있다. UTF-8은 웹 페이지를 만들 때 거의 이 형식을 따르고 있다. .NET은 기본적으로 UTF-16 2바이트 유니코드를 사용한다고 보면된다. 여기서 설명할 부분은 유니코드를 어떻게 활용하여 데이터를 C#에서 어떻게 한글처리에 이용할지 보여주는데 목표를 두고 있으므로 유니코드에 대한 상세한 설명은 생략하도록 하겠다.

완성형 한글의 Unicode 범위는 AC00에서부터 D7AF(정확히는 D79F) 범위에 걸쳐 매핑 되어 있다. 한글 자모의 경우 Unicode 범위는 1100에서부터 11FF 범위에 걸쳐 있다.(그림 참조)

 

[if gte vml 1]>

 

[그림] 완성형 한글 유니코드(AC00~D7AF)

 

[if gte vml 1]>

한글 자모 유니코드(1100~11FF)

 

이를 베이스 코드로 활용하여 유니코드에 대한 활용을 해 볼 수 있습니다.

 

3.2 한글 처리를 위한 기초 함수

, 이제 한글 처리를 위한 기본 함수들을 만들어 보겠다. 한글은 한글자가 초성, 중성, 종성의 기본 자모로 이루어지는 형태의 문자이다. 한글은 아래 표의 24자의 자모 조합을 통해 만들어진다.

자음 : ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅊㅋㅌㅍㅎ

모음 : ㅏㅑㅓㅕㅗㅛㅜㅠㅡㅣ

 

이제 한글처리를 위한 기본 기능인 자모 분리와 결합을 하는 함수를 완성형 유니코드를 이용하여 만들어보기로 하겠다. 유니코드 표를 보면 한글이 사전순으로 정리되어 있다는 것을 느낄 수 있었을 것이다.(. , , ……) 이걸 감안하면 초성 자음과 종성 자음의 거리 계산을 통해 각 자음과 모음을 매칭시킬 수 있다는 걸 알 수 있을 것이다.

기초 데이터를 사전순으로 만들어 보면 다음과 같다.

// 초성, 중성, 종성에 대한 코드 테이블.

private static string m_ChoSungTbl =

"ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ";

private static string m_JungSungTbl =

"ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ";

private static string m_JongSungTbl =

" ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ";

private static ushort m_UniCodeHangulBase = 0xAC00;

private static ushort m_UniCodeHangulLast = 0xD79F;

 

순서대로 초성자, 중성자, 종성자의 사전 순서라고 보면 된다. 맨 아래쪽의 경우 한글유니코드에 대한 시작과 종료 인덱스이다. 종성자의 경우 공백이 맨 앞에 추가되어 있는데, 이는 받침이 없는 글자를 위해 공백 한칸을 비워두었다. 이를 이용해 유니코드의 위치를 계산할 수 있게 된다.

자소 결합 계산 식을 만들어 보면 다음과 같다.

한글코드 위치 = 한글 시작위치+(초성 인덱스*21+ 중성 인덱스)*28+종성 인덱스

) = 0xAC00+(0*21+0)*28+1 = 0xAC01

 

이걸 이제 C#으로 코딩만 하면 자소 결합을 하는 함수를 만들 수 있게 된다.

//자소 결합

public static string MergeJaso(string choSung, string jungSung, string jongSung)

{

    int ChoSungPos, JungSungPos, JongSungPos;

    int nUniCode;

 

    ChoSungPos  = m_ChoSungTbl.IndexOf(choSung);     // 초성 위치

    JungSungPos = m_JungSungTbl.IndexOf(jungSung);   // 중성 위치

JongSungPos = m_JongSungTbl.IndexOf(jongSung);   // 종성 위치

 

    // 앞서 만들어 낸 계산식

    nUniCode =

m_UniCodeHangulBase + (ChoSungPos * 21 + JungSungPos) * 28 + JongSungPos;

    // 코드값을 문자로 변환

char temp = Convert.ToChar(nUniCode);

 

    return temp.ToString();

}

 

 

자소를 결합하는 함수를 만들어 봤으니, 이제 한글의 자소를 분리하는 함수를 만들어보도록 하겠다. 자소 분리는 위의 식의 역순을 따른다고 보면 된다. 소스는 다음과 같다.

//자소 분리(초성+중성+종성)

public static HanChar DivideJaso(char hanChar)

{

    int ChoSung, JungSung, JongSung; // 초성,중성,종성의 인덱스

    HanChar hc;                      // 분리된 자소를 담기 위한 자료 구조

    ushort temp = 0x0000;            // 임시로 코드값을 담을 변수

 

//Char 16비트 부호없는 정수형 형태로 변환 - Unicode

    temp = Convert.ToUInt16(hanChar);

 

// 캐릭터가 한글이 아닐 경우 처리

    if ((temp < m_UniCodeHangulBase) || (temp > m_UniCodeHangulLast))

return new HanChar("NH", hanChar, null);            

 

    // nUniCode에 한글코드에 대한 유니코드 위치를 담고 이를 이용해 인덱스 계산.

    int nUniCode = temp - m_UniCodeHangulBase;

    ChoSung = nUniCode / (21 * 28);

    nUniCode = nUniCode % (21 * 28);

    JungSung = nUniCode / 28;

    nUniCode = nUniCode % 28;

    JongSung = nUniCode;

 

// 코드테이블 내의 인덱스를 통해 초성, 중성, 종성자를 뽑아서 HanChar 에 담음.

    hc = new HanChar("H", hanChar, new char[]{m_ChoSungTbl[ChoSung], m_JungSungTbl[JungSung], m_JongSungTbl[JongSung]});

 

    return hc;

}

 

한글의 기본 단위는 초성, 중성, 종성으로 이루어진 자소 단위를 기반으로 한다. 한글 자연어에 대한 처리를 위해서 이에 대한 처리 루틴은 필수적이다. 따라서, 자소의 분리와 결합을 위한 함수를 앞에서와 같이 만들어 보았다.
[코멘트] 좋음
2007-02-11 05:54
 dontcryme  dontcryme님께 메시지 보내기dontcryme님을 내 주소록에 추가합니다.dontcryme님의 개인게시판 가기 
재밌게 잘봤습니다.

좋은 강좌

감사해요^^
저장 취소
[코멘트] 좋음
2007-06-23 23:10
 민  민님께 메시지 보내기민님을 내 주소록에 추가합니다.민님의 개인게시판 가기 
다음강좌 계속 기다리고 있습니다.

언제 짧게라도 글을 적어주시면... 후배 프로그래머들에게 매우 도움이 된답니다.
저장 취소
[코멘트] 좋음
2006-08-20 18:11
 inobae  inobae님께 메시지 보내기inobae님을 내 주소록에 추가합니다.inobae님의 개인게시판 가기 
아~~ 지멋대로네요. 그림을 아무리 올려도 그림이 안보이네요.... 별로 중요한 그림 아니니 포기하고 보세요.- -;
다음에는 사전과 검색이 올라갈 순서가 되겠군요. 에거 시간날때 마다 정리한다고 하는데 조금 엉망입니다.
도움이 될런지도 모르겠고요.ㅎㅎㅎ
저장 취소
[코멘트] 좋음
2006-08-22 23:52
 mohalsae  mohalsae님께 메시지 보내기mohalsae님을 내 주소록에 추가합니다.mohalsae님의 개인게시판 가기 
우와 제가 한글처리를 잘 몰랐었는데요.
많이 배우고 갑니다. 감사합니다~
저장 취소
[코멘트] 좋음
2006-08-23 17:53
 4winners  4winners님께 메시지 보내기4winners님을 내 주소록에 추가합니다.4winners님의 개인게시판 가기 
좋은 강좌네요 ^^* 전에 어느분이 유니코드 체계를 물어봐서 대답해줬는데

이글이 일찍 올라왔으면 이걸 확인하라고 했으면 좋았을것을 ^^*
저장 취소
[코멘트] 좋음
2006-08-25 23:04
 inobae  inobae님께 메시지 보내기inobae님을 내 주소록에 추가합니다.inobae님의 개인게시판 가기 
잘 봐주시니 감사하네요.^^
다음걸 주말에 정리하려 했는데 이번주는 학회때문에 쉬고 담주에나 올려야 겠습니당.
저장 취소
[코멘트] 좋음
2006-09-18 19:52
 inobae  inobae님께 메시지 보내기inobae님을 내 주소록에 추가합니다.inobae님의 개인게시판 가기 
0xac01 을 "각"이라는 문자로 출력하고 싶다는 질문이 들어와서 한자 적습니다.^^;
유니코드를 그대로 한글로 보여주면 되기때문에... 아래처럼 하면 hangul이라는 변수에 "각"이 바로 저장됩니다.
string hangul = ((char)0xac01).ToString();

게으름을 핑계로 다음강좌를 계속 미뤄 왔네요... 이번 주말에는 필히 올리고 말겠습니다. 샘플 만들어야지 하다가.... 시간만 보내고 만들지는 않고 그러고 있네요.ㅡ_ㅡ;
저장 취소
[코멘트] 좋음
2008-03-04 12:24
 inobae  inobae님께 메시지 보내기inobae님을 내 주소록에 추가합니다.inobae님의 개인게시판 가기 
자소 분리 코드에 쓰인 HanChar 구조체 소스가 포함안하고 올렸다고 쪽지가 와서...
자소 분리 결과를 구조체에 넣지 않고 그냥 char 배열로 리턴하도록 수정한 소스입니다.^^;

// 자소분리
public static char[] DivideJaso(char hanChar)
{
int ChoSung, JungSung, JongSung;


ushort temp = 0x0000;

try
{
temp = Convert.ToUInt16(hanChar); //Char을 16비트 부호없는 정수형 형태로 변환
}
catch (Exception e)
{
//return e.ToString();
}

if ((temp < m_UniCodeHangulBase) || (temp > m_UniCodeHangulLast)) return null;

//초성자, 중성자, 종성자 Index계산
int nUniCode = temp - m_UniCodeHangulBase;
ChoSung = nUniCode / (21 * 28);
nUniCode = nUniCode % (21 * 28);
JungSung = nUniCode / 28;
nUniCode = nUniCode % 28;
JongSung = nUniCode;

return new char[] { m_ChoSungTbl[ChoSung], m_JungSungTbl[JungSung], m_JongSungTbl[JongSung] };
}
저장 취소
코멘트쓰기
  좋음   놀람   궁금   화남   슬픔   최고   침묵   시무룩   부끄럼   난감
* 코멘트는 500자 이내(띄어쓰기 포함)로 적어주세요.
목록 보기   지금 보고 계시는 글을 회원님의 my Mblog >> 스크랩에 넣어두고 다음에 바로 보실 수 있습니다.  
회사소개  |   개인정보취급방침  |  제휴문의  |   광고문의  |   E-Mail 무단수집거부  |   고객지원  |   이용안내  |   세금계산서
사업자등록번호 안내: 220-81-90008 / 통신판매업신고번호 제 2017-서울구로-0055호 / 대표: 홍영준, 서민호
08390, 서울시 구로구 디지털로32길 30, 1211호 / TEL. 02_6719_6200 / FAX. 02-6499-1910
Copyright ⓒ (주) 데브피아. All rights reserved.