본문 바로가기

[IT/Programming]/Algorithm/Database

한글 초성검색 in Javascript

# 한글 초성검색 in Javascript 한글의 위대함을 한껏 활용하기 위해 초성검색을 구현해 봅시다. ## TOC ## 한글 Encoding in Javascript 자바스크립트의 문자열은 내부적으로 16비트 유니코드로 처리 . 유니코드에서 한글은 코드값 OxAC00부터 시작하며, 초성 19 / 중성 21 / 종성 28 개의 조합 순으로 코드가 배열. 유니코드에 대한 공식 설명은 에서... 초성, 중성, 종성의 자모 순서는 에서... (Hangul Syllables 부분에 한글 음절에 대한 유니코드표)
  • Hangul Array
  • 초성 "ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"
  • 중성 "ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ"
  • 종성 "", "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"
한글 Unicode
## 초성, 중성, 종성 분리하기 초성에 8 bit, 중성에 8 bit, 종성에 8 bit 형태로 encoding 이 되어 있으면 굳이 이런 작업이 필요 없겄지만;;; 쌍 기역 "ㄲ" 같은 것들도 있어서(?) 이런 24 bit encoding 이 더 효율이 좋은거 같진 않군요. 아무튼 16 bit unicode 로 이루어진 한글 string data 를 잘 분석해서 초성, 중성, 종성으로 분리해내 봅시다. (뭐 활용하고자 하는 방법에 따라 더 분리해내는게 필요할수도 있긴 하겠네요.) 유니코드에서 특정 글자의 코드 값은 다음과 같은 식으로 생각해 볼 수 있습니다. ( \text{초성} \times 21 \times 28 ) + ( \text{중성} \times 28 ) + \text{종성} \\ = \big( ( \text{초성} \times 21 ) + \text{중성} \big) \times 28 + \text{종성} 정확한 한글 유니코드 값은 \text{한글 유니코드 값} = \text{0xAC00} + \big( ( \text{초성} \times 21 ) + \text{중성} \big) \times 28 + \text{종성} 라고 하는군요 . 정리 해주셔서 감사;;; 이 블로그 글쓴이가 정리 안해주셨으면 이거 알아내는데 엄청 고생했을듯 =ㅂ=;;; 위 식에서 초성 / 중성 / 종성 은 첫 글자를 0 으로 하는 해당 글자의 상에서의 위치. 이런 정보를 바탕으로 다음과 같은 javascript code 를 통해 초성 / 중성 / 종성 을 분리해 낼 수 있는듯. ```[.linenums.lang-js] var rCho = ["ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"]; var rJung = ["ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ"]; var rJong = ["", "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"]; var cho, jung, jong; var sTest="탱"; var nTmp=sTest.charCodeAt(0) - 0xAC00; jong=nTmp % 28; // 종성 jung=( (nTmp-jong)/28 ) % 21; // 중성 cho=( ( (nTmp-jong)/28 ) - jung ) / 21; // 종성 console.log( "초성:"+rCho[cho]+"\n" +"중성:"+rJung[jung]+"\n" +"종성:"+rJong[jong] ); ```/ ## Test it yourself ```[#hangul-split-result.linenums] ```/ ### Code





## 초성검색

구현된 초성검색은 kipid's blog - Lists 에서 확인하실 수 있습니다. Fuzzy search 버튼 눌러 보세요. 여기에 코드 정리는 나중에 할 예정. (딱히 기약은 없음.) 초성검색과 비슷한 Fuzzy search 글 kipid's blog - Auto Completion, and Fuzzy Search 참고해 보셔도 좋습니다.



## RRA

  1. dream.ahboom.net - 한글 유니코드 자소 분리방법, 2010-02-25
  2. www.unicode.org - Hangul Jamo.pdf and Hangul Compatibility Jamo.pdf and Hangul Syllables.pdf
  • 안녕하세요 2019.03.01 09:50 댓글주소 수정/삭제 댓글쓰기

    자모분리는 있는데, 초성검색은 아직 안 보이네요... 혹시 더 작성하실 계획인가요? 개인적으로 쓰려는데 제대로 된 자바스크립트 초성검색 코드를 찾기가 참 어렵네요. 능력이 있다면 직접 만들었겠습니다만...

    • 그렇네요. 작성하다 만 글이었던듯;;; 초성검색은
      https://kipid.tistory.com/entry/Lists
      여기서 실행해 보실수 있습니다. 언제 글을 완성할지는 모르겠네요;;; 약간 복잡하긴 합니다.
      검색하고자 하는 텍스트로 자모분리 시키고 검색을 하면 되긴 하는데... 구현하고자 하는 구체적인 방향에 따라서 코드가 달라질듯 하네요.

      https://kipid.tistory.com/entry/Auto-Completion-and-Fuzzy-Search
      여기글도 참고해 보시길...

  • wildman 2019.10.28 19:36 댓글주소 수정/삭제 댓글쓰기

    한글 초성 중성 종성으로 분리 해 봤습니다.
    for(i=j;i<='힣'.charCodeAt(0);i++){
    if( (i-ja_base-12593) / 588 == parseInt((i-ja_base-12593) / 588) ) {
    ja_base = i - 12593;//31439
    mo_base = i - 12623;//31409
    }
    cho = String.fromCharCode( 12593 + parseInt((i - 31439 - 12593) / 588) );
    jung = String.fromCharCode( 12623 + parseInt((i - mo_base - 12623) / 28) );
    jong = String.fromCharCode( 12593 + (i-ja_base-12593)%28-1 );

    if(cho >= "ㄳ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㄵ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㄶ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㄺ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㄻ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㄼ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㄽ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㄾ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㄿ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㅀ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(cho >= "ㅄ") cho = String.fromCharCode(cho.charCodeAt(0)+1);
    if(jong < "ㄱ") jong = "";
    if(jong >= "ㄸ") jong = String.fromCharCode(jong.charCodeAt(0)+1);
    if(jong >= "ㅃ") jong = String.fromCharCode(jong.charCodeAt(0)+1);
    if(jong >= "ㅉ") jong = String.fromCharCode(jong.charCodeAt(0)+1);

    str += ++l + " " + String.fromCharCode(i)+" "+i + " ";
    str += cho +" ";//초성
    str += jung +" ";//중성
    str += jong +" ";//종성
    str += "<br>";
    }
    str += "<br>";
    document.write(str);

    함수는 고니의꿈 글을 참조
    출처: https://goni9071.tistory.com/164 [고니의꿈]