«
in python  / #한글  

python으로 한글 자모 분리, 합치기

pip로 hangul-utils를 설치한다

$ pip install hangul-utils

설치한 후 python에서 함수를 import, 샘플 텍스트 준비

from hangul_utils import split_syllables, join_jamos

sample_text = '''[리포트]

어제만 해도 차갑던 저녁 공기가 한층 온화해졌습니다. 때맞춰 이곳 삼청동 길에도 사람들이 
붐비고 있는데, 문제는 미세먼지입니다.

대기정체로 먼지가 빠져나가지 못하면서, 내일까지는 곳곳에서 평소 두 세배 수준의 짙은 먼지가 
나타나겠고요. 연무가 남으면서 낮에도 시야가 뿌연 곳이 많겠습니다.'''

split_syllables 함수로 한글 자모를 분리한다.

jamo = split_syllables(sample_text)
print(jamo)
[ㄹㅣㅍㅗㅌㅡ]

ㅇㅓㅈㅔㅁㅏㄴ ㅎㅐㄷㅗ ㅊㅏㄱㅏㅂㄷㅓㄴ ㅈㅓㄴㅕㄱ ㄱㅗㅇㄱㅣㄱㅏ ㅎㅏㄴㅊㅡㅇ 
ㅇㅗㄴㅎㅘㅎㅐㅈㅕㅆㅅㅡㅂㄴㅣㄷㅏ. ㄸㅐㅁㅏㅈㅊㅝ ㅇㅣㄱㅗㅅ ㅅㅏㅁㅊㅓㅇㄷㅗㅇ
ㄱㅣㄹㅇㅔㄷㅗ ㅅㅏㄹㅏㅁㄷㅡㄹㅇㅣ ㅂㅜㅁㅂㅣㄱㅗ ㅇㅣㅆㄴㅡㄴㄷㅔ, ㅁㅜㄴㅈㅔㄴㅡㄴ 
ㅁㅣㅅㅔㅁㅓㄴㅈㅣㅇㅣㅂㄴㅣㄷㅏ.

ㄷㅐㄱㅣㅈㅓㅇㅊㅔㄹㅗ ㅁㅓㄴㅈㅣㄱㅏ ㅃㅏㅈㅕㄴㅏㄱㅏㅈㅣ ㅁㅗㅅㅎㅏㅁㅕㄴㅅㅓ, 
ㄴㅐㅇㅣㄹㄲㅏㅈㅣㄴㅡㄴ ㄱㅗㅅㄱㅗㅅㅇㅔㅅㅓ ㅍㅕㅇㅅㅗ ㄷㅜ ㅅㅔㅂㅐ ㅅㅜㅈㅜㄴㅇㅢ 
ㅈㅣㅌㅇㅡㄴ ㅁㅓㄴㅈㅣㄱㅏ ㄴㅏㅌㅏㄴㅏㄱㅔㅆㄱㅗㅇㅛ. ㅇㅕㄴㅁㅜㄱㅏ ㄴㅏㅁㅇㅡㅁㅕㄴㅅㅓ 
ㄴㅏㅈㅇㅔㄷㅗ ㅅㅣㅇㅑㄱㅏ ㅃㅜㅇㅕㄴ ㄱㅗㅅㅇㅣ ㅁㅏㄶㄱㅔㅆㅅㅡㅂㄴㅣㄷㅏ.

분리한 자모를 숫자로 만들기 위해 텍스트에서 고유한 문자들을 추린 다음, 문자-숫자간 1:1 대응하는 사전을 만든다.

chars = list(set(jamo))
char_to_ix = { ch:i for i,ch in enumerate(chars) }
ix_to_char = { i:ch for i,ch in enumerate(chars) }
print(char_to_ix)
{'ㅑ': 0, 'ㅕ': 19, '\n': 1, 'ㄴ': 21, 'ㅁ': 22, ' ': 2, 'ㄶ': 29, 'ㅗ': 23, 'ㅐ': 3,
 'ㅈ': 20, 'ㅆ': 4, 'ㅔ': 5, 'ㅇ': 24, 'ㅅ': 25, 'ㅛ': 6, 'ㅢ': 26, 'ㅊ': 27, 'ㄲ': 7,
 'ㅃ': 8, 'ㅍ': 37, 'ㄷ': 9, 'ㅡ': 10, 'ㅝ': 15, 'ㅘ': 30, 'ㅏ': 31, 'ㅓ': 12, 'ㅌ': 32, 
 'ㅣ': 34, ',': 13, 'ㅂ': 14, 'ㄹ': 33, 'ㅜ': 16, '.': 11, 'ㅎ': 35, ']': 36, 'ㄸ': 17, 
 'ㄱ': 18, '[': 28}

사전을 이용하여 자모를 숫자로 변환한다.

jamo_numbers = [char_to_ix[x] for x in jamo]
print(jamo_numbers)
[28, 33, 34, 37, 23, 32, 10, 36, 1, 1, 24, 12, 20, 5, 22, 31, 21, 2, 35, 3, 9, 23, 2,
 27, 31, 18, 31, 14, 9, 12, 21, 2, 20, 12, 21, 19, 18, 2, 18, 23, 24, 18, 34, 18, 31,
 2, 35, 31, 21, 27, 10, 24, 2, 24, 23, 21, 35, 30, 35, 3, 20, 19, 4, 25, 10, 14, 21,
 34, 9, 31, 11, 2, 17, 3, 22, 31, 20, 27, 15, 2, 24, 34, 18, 23, 25, 2, 25, 31, 22,
 27, 12, 24, 9, 23, 24, 2, 18, 34, 33, 24, 5, 9, 23, 2, 25, 31, 33, 31, 22, 9, 10,
 33, 24, 34, 2, 14, 16, 22, 14, 34, 18, 23, 2, 24, 34, 4, 21, 10, 21, 9, 5, 13, 2, 
 22, 16, 21, 20, 5, 21, 10, 21, 2, 22, 34, 25, 5, 22, 12, 21, 20, 34, 24, 34, 14, 21, 
 34, 9, 31, 11, 1, 1, 9, 3, 18, 34, 20, 12, 24, 27, 5, 33, 23, 2, 22, 12, 21, 20, 34, 
 18, 31, 2, 8, 31, 20, 19, 21, 31, 18, 31, 20, 34, 2, 22, 23, 25, 35, 31, 22, 19, 21, 
 25, 12, 13, 2, 21, 3, 24, 34, 33, 7, 31, 20, 34, 21, 10, 21, 2, 18, 23, 25, 18, 23, 
 25, 24, 5, 25, 12, 2, 37, 19, 24, 25, 23, 2, 9, 16, 2, 25, 5, 14, 3, 2, 25, 16, 20, 
 16, 21, 24, 26, 2, 20, 34, 32, 24, 10, 21, 2, 22, 12, 21, 20, 34, 18, 31, 2, 21, 31, 
 32, 31, 21, 31, 18, 5, 4, 18, 23, 24, 6, 11, 2, 24, 19, 21, 22, 16, 18, 31, 2, 21, 31, 
 22, 24, 10, 22, 19, 21, 25, 12, 2, 21, 31, 20, 24, 5, 9, 23, 2, 25, 34, 24, 0, 18, 31,
 2, 8, 16, 24, 19, 21, 2, 18, 23, 25, 24, 34, 2, 22, 31, 29, 18, 5, 4, 25, 10, 14, 21,
 34, 9, 31, 11]

조립은 분해의 역순으로 진행한다. ix_to_char 사전을 이용하여 다시 숫자를 문자로 변환하고 join_jamos로 분리한 자모를 합친다.

restored_jamo = ''.join([ix_to_char[x] for x in jamo_numbers])
restored_text = join_jamos(restored_jamo)
print(restored_text)
[리포트]

어제만 해도 차갑던 저녁 공기가 한층 온화해졌습니다. 때맞춰 이곳 삼청동 길에도 사람들이 
붐비고 있는데, 문제는 미세먼지입니다.

대기정체로 먼지가 빠져나가지 못하면서, 내일까지는 곳곳에서 평소 두 세배 수준의 짙은 먼지가 
나타나겠고요. 연무가 남으면서 낮에도 시야가 뿌연 곳이 많겠습니다.