한글과 유니코드에 대해
유니코드 상에서 한글의 위치에 대해서는 https://darrengwon.tistory.com/1425 를 참고해봅시다.
한글의 음절(Hangle Syllables)은 유니코드 상의 Hangul Jamo의 조합으로 표현할 수 있습니다.
예를 들어, "한"은 유니코드상 U+d55c에 해당합니다.
"한"은 ㅎ, ㅏ, ㄴ이라는 자모로 구성되어 있기도 합니다. Hangul Jamo 상에서 다음과 같은 배치를 가지고 있기도 합니다.
ㅎ | U+1112 |
ㅏ | U+1161 |
ㄴ | U+11AB |
여기서 우리는 Hangul Jamo에 특정 값을 곱하거나 더하여, Hangle Syllables를 만드는 공식을 도출할 수 있을 것이라 추측할 수 있습니다.
Hangul Jamo to Hangle Syllables
Hangle syllables와 Hangul Jamo 사이의 공식은 아래와 같이 표현할 수 있습니다.
초/중/종성의 구분은 유니코드 상의 Hangul Jamo의 순서에 근거한 것입니다.
Hangul Syllables = 0xAC00 + 28*21*(초성 index) + 28*(중성 index) + (종성 index)
// 16진수, 10진수 matching
0xAC00(44032)
0x24C(28 * 21)
0x1C(28)
// Hangul Jamo의 초/중/종성의 index는 아래에 따름.
const 초성들 = ["ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"];
const 중성들 = ["ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ"];
const 종성들 = ["", "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"];
- 종성의 0번 인덱스에 빈 문자열을 둔 이유는 음절은 종성이 없이 표현될 수 있다는 점에서 0번 인덱스를 할당한 것입니다. 예를 들어 "하"는 종성이 없는 음절이죠.
- 28은 종성의 배열 크기이며, 21은 중성의 배열 크기입니다.
Hangle Syllables to Hangul Jamo
위 공식을 역으로 적용하면, 이제 음절을 자모로 분리할 수 있을 것입니다.
Hangul Syllables = 0xAC00 + 28*21*(초성 index) + 28*(중성 index) + (종성 index)
위 코드에서 0xAC00을 뺀 후에, 각자의 index를 역으로 구해가는 식을 간단하게 구할 수 있을 겁니다.
const target = char.charCodeAt(0) - "가".charCodeAt(0);
// 종성. 28로 나눈 나머지값. 없으면 0이 되겠죠?
종성 index = target % 28;
// 중성. 종성 값을 제외한 후 28로 나눈 후 21로 나눈 값의 나머지를 할당함
중성 index = ((target - 종성 index) / 28) % 21;
// 초성.
초성 index = ((target - 종성 index) / 28 - 중성 index) / 21;
* 겹받침의 추가적인 분리?
아래 글을 쓰신 분은 종성 중 겹받침(ex - 않의 'ㄴㅎ')까지 분리하시는 분이 계시네요. 저는 여기까지는 필요하지 않아서 따로 구현하지는 않았지만, 필요하시면 참고 바랍니다.
ref)
https://github.com/bluewings/korean-regexp
'🤖 ML > 🔠 NLP' 카테고리의 다른 글
유니코드와 한글의 영역 (0) | 2021.05.31 |
---|---|
데이터 정제를 위한 정규식 tips (0) | 2021.02.14 |