개발한 이유
https://spaces.w3schools.com/ 에 파일을 업로드할 때 파일 이름이 한글로 되어 있으면 업로드 되지 않는다. 그래서 한글 파일이름을 알파벳으로 변환해야 겠다고 생각했다.
국립국어원 로마자 표기법 ( https://kornorms.korean.go.kr/m/m_regltn.do?regltn_code=0004#a ) 에서 표기 방법이 음에 따라 동일한 한글자모가 다른 알파벳으로 표현되도록 되어 있다. 이러한 방식의 가장 큰 문제점은 한글 로마자 변환하기가 어렵고 또한 로마자로 변환한 것을 한글로 변환할 경우 원래 한글과 다르게 될 수 있다.
위 표기법에 따른 파이썬을 이용한 변환 프로그램을 발견하였다. 참고하면 좋을 것 같다. https://github.com/YiHoze/texwrapper
여기서는 한글 로마자 변환을 글자대 글자 (한글자모에 알파벳을 할당하고 글자수도 동일하게 맞춤. 예, '왥' = 'ㅇ' + 'ㅗ' + 'ㅏ' + 'ㅣ' + 'ㄹ' + 'ㄱ' ↔ 'j' + 'o' + 'a' + 'i' + 'l' + 'g')로 단순하게 변환하므로써 한글에서 로마자로 로마자에서 한글로 변환할 때 용이하고 양방향 변환시 원래대로 변환되게 하는 것이 목적이다.
한글 유니코드 테이블
한글자음모음은 '0x3131' (십진수 12593, 'ㄱ') 부터 '0x3163'(십진수 12643, 'l') 까지 이고,
한글 글자는 '0xac00' (16진수 'AC00', 10진수 44032, '가')부터 '0xd7a3' (16진수 'D7A3', '힣') 까지 이고,
이후부터 '0xd800' (16진수 'D800') 까지 기타 한글자모 조합이 할당되어 있다.
한글 - alphabet 할당
0: '' - '',
1: 'ㄱ' - 'g',
2: 'ㄲ' - 'gg',
3: 'ㄳ' - 'gs',
4: 'ㄴ' - 'n',
5: 'ㄵ' - 'nz',
6: 'ㄶ' - 'nh',
7: 'ㄷ' - 'd',
8: 'ㄸ' - 'dd',
9: 'ㄹ' - 'l',
10: 'ㄺ' - 'lg',
11: 'ㄻ' - 'lm',
12: 'ㄼ' - 'lb',
13: 'ㄽ' - 'ls',
14: 'ㄾ' - 'lt',
15: 'ㄿ' - 'lp',
16: 'ㅀ' - 'lh',
17: 'ㅁ' - 'm',
18: 'ㅂ' - 'b',
19: 'ㅃ' - 'bb',
20: 'ㅄ' - 'bs',
21: 'ㅅ' - 's',
22: 'ㅆ' - 'ss',
23: 'ㅇ' - 'j', # 'ㅇ'에 할당 알파벳 'j'에 주의하라,
24: 'ㅈ' - 'z',
25: 'ㅉ' - 'zz',
26: 'ㅊ' - 'c',
27: 'ㅋ' - 'k',
28: 'ㅌ' - 't',
29: 'ㅍ' - 'p',
30: 'ㅎ' - 'h',
31: 'ㅏ' - 'a',
32: 'ㅐ' - 'ai', # 'ㅏ' + 'ㅣ'
33: 'ㅑ' - 'ya', # 'ㅣ' + 'ㅏ' 가 합친 것으로 생각할 때 'ia'가 적당할 같지만 현재 통상적으로 사용하는 'ya'로 함.
34: 'ㅒ' - 'yai', # 'ㅑ' + 'ㅣ'
35: 'ㅓ' - 'e', # 'ㅓ' 을 알파벳 한자로 표현할 수 있는 적당한 글자가 없고 현재 통상적으로 사용하는 'eo'는 두글자라 다른 곳에 할당되지 않는 'e'를 'ㅓ'에 매치시켰다.
36: 'ㅔ' - 'ei', # 'ㅓ' + 'ㅣ'
37: 'ㅕ' - 'ye', # 'ㅣ' + 'ㅓ' 가 합친 것으로 생각할 때 'ie'로 표시하면 어색하고, 현재 통상적으로 사용하는 'yeo'로 하면 3자가 되어서 'e'를 'ㅓ'에 매치한 것과 같이 'ye'로 매치시켰다.
38: 'ㅖ' - 'yei', # 'ㅕ' + 'ㅣ'
39: 'ㅗ' - 'o',
40: 'ㅘ' - 'oa',
41: 'ㅙ' - oai',
42: 'ㅚ' - 'oi',
43: 'ㅛ' - 'yo',
44: 'ㅜ' - 'u',
45: 'ㅝ' - 'ue', # 'ㅜ' + 'ㅓ', 'u' + 'e'
46: 'ㅞ' - 'uei', # 'ㅜ' + 'ㅓ' + 'ㅣ'
47: 'ㅟ' - 'ui',
48: 'ㅠ' - 'yu', # 'ㅣ' + 'ㅜ' 가 합친 것으로 생각할 때 'iu'로 표시하면 어색하고 현재 통상적으로 사용하고 있는 'yu'로 함.
49: 'ㅡ' - 'w', # 'ㅡ'를 표시할 적당한 알파벳이 없고 현재 통상적으로 사용하는 'eu'는 두 글자라 다른 곳에 할당되지 않는 'w'를 'ㅡ'에 매치시켰다.
50: 'ㅢ' - 'wi', # 'ㅡ' + 'ㅣ'
51: 'ㅣ' - 'i'
}
단어를 주면 알파벳을 그대로 두고 한글자모를 알파벳으로 변환
입력: 단어
- 로마자와 한글이 섞여 있는 단어
출력: 로마자로 변환된 단어
- 출력 단어에서 원래 한글에서 변환된 로마자인지 원래 로마자인지 구분을 위해 ' ' (빈칸)을 넣어주었고,
- 한글 글자는 여러개의 자모로 구성되어 있어 한자 한자 구분하기 위해서 '_' (밑줄)을 사용하였다.
- 나중에 로마자로 된 문장을 한글이 포함된 문장으로 변환하려면 위 ' ' 과 '_'을 구분자로 사용한다. 원래 문장에 '_' 이 포함되어 있었던 경우는 예외적으로 처리해야 할 것 같다.
실행 부분
1. 클래스 Han2Eng (변환 함수가 사용할 변수 선언 및 함수 선언을 포함함) 할당
2. 한글 포함 문장 출력
3. 한글 포함 문장을 로마자 문장으로 변환: aHanStr2aEngStr(aHanStr)
4. 결과 출력
if __name__ == "__main__":
H2E = Han2Eng()
# 초성 19자: ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ
# 중성 21자: ㅏ,ㅐ,ㅑ,ㅒ, ㅓ,ㅔ,ㅕ,ㅖ, ㅗ,ㅘ,ㅙ,ㅚ, ㅛ, ㅜ,ㅝ,ㅞ,ㅟ, ㅠ, ㅡ,ㅢ,ㅣ
# 종성이 28자: '','ㄱ','ㄲ','ㄳ','ㄴ','ㄵ','ㄶ','ㄷ',
# 'ㄹ','ㄺ','ㄻ','ㄼ','ㄽ','ㄾ','ㄿ','ㅀ',
# 'ㅁ','ㅂ','ㅄ','ㅅ','ㅆ','ㅇ','ㅈ','ㅊ','ㅋ','ㅌ','ㅍ','ㅎ'
aHanStr = 'aㅁㅋa가깩냒댻떤렍멶볟뽈솱쐚욃죬쭕춾퀧튐퓹흢긧깠냉댲떛렄멭볖뼿'
print(aHanStr)
aEngStr = H2E.aHanStr2aEngStr(aHanStr)
print(aEngStr)
클래스 선언
class Han2Eng:
aHanStr2aEngStr() 함수 - 한글이 포함된 문장을 로마자 문장으로 변환
한글이 포함된 문장 aHanStr 입력하면 한자씩 나눠서 문자를 로마자로 변환 aHanChar2aEngStr() 한다.
def aHanStr2aEngStr(self, aHanStr):
aEngStr = ''
for c in aHanStr:
aEngStr += self.aHanChar2aEngStr(c)
return aEngStr
aHanChar2aEngStr() 함수 - 입력문자를 로마자로 변환
1. lookupHanChar() 함수를 통해 입력문자(aHanChar)를 입력 받아 한글 문자표에서 초성, 중성, 종성의 위치값(iAtFirst, iAtMiddle, iAtLast)을 돌려받고, 한글과 알파벳 변경시점을 insertChar로 돌려받는다 -
2. 영어, 한글자모, 한글문자 중 소속에 따라 처리한다. 초성의 위치를 iAtFirst에 받
(1) 영어이면 입력문자를 출력변수 aEngChar에 전달하고,
(2) 한글자모이면 한글자모에 해당하는 알파벳을 전달하고,
(3) 한글문자이면 한글 초성, 중성, 종성의 조합 알파벳을 전달한다.
- 2.(1) 영어이면 (if iAtFirst == -2), 출력문자(aEngStr)에 영한변환 유무(insertChar)와 입력문자를 할당하고,
- 2.(2) 한글자모이면 (if iAtFirst == -1), 출력문자에 영한변환 유무와 입력한글자모 딕셔너리(dictHanLetterRomainzed)에 해당하는 로마자를 할당한다.
- 2.(3) 한글문자이면 (if iAtFirst == 0), 출력문자에 영한변환 유무와 입력한글문자 초, 중, 종성 딕셔너리(dictFirstLetterRomanized, dictMiddleLetterRomanized, dictLastLetterRomanized)에 해당하는 로마자를 할당한다.
def aHanChar2aEngStr(self, aHanChar):
iAtFirst, iAtMiddle, iAtLast, insertChar = self.lookupHanChar(aHanChar)
if iAtFirst == -2:
aEngStr = insertChar + aHanChar
elif iAtFirst == -1:
aEngStr = insertChar + self.dictHanLetterRomanized[iAtLast] + '_' # '_' 한글글자 구분 가독성을 위해서 넣음
else:
aEngStr = (
insertChar
+ self.dictFirstLetterRomanized[iAtFirst]
+ self.dictMiddleLetterRomanized[iAtMiddle]
+ self.dictLastLetterRomanized[iAtLast]
+ '_'
)
print(aHanChar, aEngStr)
return aEngStr
lookupHanChar() 함수 - 입력문자가 영어인지 한글자모인지 한글문자인지를 돌려주고, 영한변환 가부를 돌려준다. 한글문자인 경우에 초성, 중성, 종성 딕셔너리에서 위치 값을 돌려준다.
1. 입력문자(aHanChar)의 유니코드표에서 위치값(ord(aHanChar))을 구한 후
(1) 위치값이 12593과 12643 사이의 값 - 한글자모 위치인 경우, iAtFirst에 한글자모임을 나타낼 수 있게 -2를 할당하고, 자모의 위치값에서 'ㄱ'의 위치값을 빼고 +1(+1 한 이유는 유니코드표에서는 없지만 빈칸(' ')을 자모딕셔너리에서 빈칸(' ')을 0이 되게, 'ㄱ'이 1이 되게 하기 위해서)로 하여 iAtLast 에 할당한다. iAtMiddle에 0을 할당한다.
(2) 위치값이 유니코드표 상에서 한글문자의 위치이면 (ord('가')에서부터 ord('힣')까지), iAtFirst에 한글 초성딕셔너리에서 초성의 위치값을, iAtMiddle에 한글 중성딕셔너리에서 중성의 위치값을, iAtLast에 한글 종성딕셔너리에서 종성의 위치값을 할당한다.
(3) 위치값이 한글자모나 한글문자가 아니면 iAtFirst 에 -2를 할당한다. iAtMiddle와 iAtLast에 각각 0을 할당한다.
2. 이전 문자와 입력문자가 다른 경우 insertChar 에 빈칸(' ')을 할당한다. 이전문자가 한글인지 아닌지는 self.flagHan 에 저장하여 lookupHanChar() 함수가 호출될 때 입력문자와 비교하여 결정한다.
def lookupHanChar(self, aHanChar='깐'):
# pos = int(aHanChar.encode('utf-16be').hex(), 16)
# base = int('가'.encode('utf-16be').hex(), 16) # 한글 시작 직전 위치,
pos = ord(aHanChar)
if pos >= 12593 and pos <= 12643: # 자모
iAtLast = pos - ord('ㄱ') + 1 # 제일 첫번째는 무음
iAtFirst = -1 # 한글 자모 표시
iAtMiddle = -1
if self.flagHan:
self.flagSwitch = False
insertChar = ''
else:
self.flagSwitch = True
self.flagHan = True
insertChar = ' '
elif pos >= ord('가') and pos <= ord('힣'): # 한글글자
ith = pos - ord('가')
iAtFirst = ith // (28 * 21)
iAtMiddle = ith % (28 * 21) // 28
iAtLast = ith % (28 * 21) % 28 % 28 # iAtLast = ith % 28
if self.flagHan:
self.flagSwitch = False
insertChar = ''
else:
self.flagSwitch = True
self.flagHan = True
insertChar = ' '
else:
iAtFirst = -2 # 한글이 아님 표시
iAtMiddle = -2
iAtLast = -2
if self.flagHan:
self.flagSwitch = True
self.flagHan = False
insertChar = ' '
else:
self.flagSwitch = False
insertChar = ''
print(iAtFirst, iAtMiddle, iAtLast)
return iAtFirst, iAtMiddle, iAtLast, insertChar
__init__ 선언
여기서 문자표 dictionary 정의하였다.
1. 자모 self.dictHanLetterRomanized
2. 초성 self.dictFirstLetterRomanized
3. 중성 self.dictMiddleLetterRomanized
4. 종성 self.dictLastLetterRomanized
self.dictFirstLetter, self.dictMiddleLetter, self.dictLastLetter 은 나중에 로마자 문장을 한글 문장으로 변환할 때 사용할 예정이고 여기서는 사용하지 않는다.
def __init__(self):
self.flagHan = False # 최초 문자가 로마자(알파벳)이라 간주함.
self.flagSwitch = False # 단어 중에서 이전 문자와 현재 문자의 종류(알파벳 또는 한글)가 바뀌지 않음
# unicode table은 연속되는 순서로 배열된 테이블이다.
# utf-8은 연속되지 않는 변환 숫자이다.
# 초성 19자: ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ
self.dictFirstLetter = {
0: 'ㄱ',
1: 'ㄲ',
2: 'ㄴ',
3: 'ㄷ',
4: 'ㄸ',
5: 'ㄹ',
6: 'ㅁ',
7: 'ㅂ',
8: 'ㅃ',
9: 'ㅅ',
10: 'ㅆ',
11: 'ㅇ',
12: 'ㅈ',
13: 'ㅉ',
14: 'ㅊ',
15: 'ㅋ',
16: 'ㅌ',
17: 'ㅍ',
18: 'ㅎ'
}
# 중성 21자:
# ㅏ, ㅐ, ㅑ, ㅒ, ㅓ, ㅔ, ㅕ, ㅖ,
# ㅗ, ㅘ, ㅙ, ㅚ, ㅛ,
# ㅜ, ㅝ , ㅞ, ㅟ, ㅠ,
# ㅡ, ㅢ, ㅣ
self.dictMiddleLetter = {
0: 'ㅏ', 1: 'ㅐ', 2: 'ㅑ', 3: 'ㅒ',
4: 'ㅓ', 5: 'ㅔ', 6: 'ㅕ', 7: 'ㅖ',
8: 'ㅗ', 9: 'ㅘ', 10: 'ㅙ', 11: 'ㅚ',
12: 'ㅛ',
13: 'ㅜ', 14: 'ㅝ', 15: 'ㅞ', 16: 'ㅟ',
17: 'ㅠ',
18: 'ㅡ', 19: 'ㅢ', 20: 'ㅣ'
}
# 종성이 28자: '','ㄱ','ㄲ','ㄳ','ㄴ','ㄵ','ㄶ','ㄷ',
# 'ㄹ','ㄺ','ㄻ','ㄼ','ㄽ','ㄾ','ㄿ','ㅀ',
# 'ㅁ','ㅂ','ㅄ','ㅅ','ㅆ','ㅇ','ㅈ','ㅊ','ㅋ','ㅌ','ㅍ','ㅎ'
self.dictLastLetter = {
0: '', 1: 'ㄱ', 2: 'ㄲ', 3: 'ㄳ',
4: 'ㄴ', 5: 'ㄵ', 6: 'ㄶ',
7: 'ㄷ',
8: 'ㄹ', 9: 'ㄺ', 10: 'ㄻ', 11: 'ㄼ', 12: 'ㄽ', 13: 'ㄾ', 14: 'ㄿ', 15: 'ㅀ',
16: 'ㅁ',
17: 'ㅂ', 18: 'ㅄ',
19: 'ㅅ', 20: 'ㅆ',
21: 'ㅇ',
22: 'ㅈ',
23: 'ㅊ',
24: 'ㅋ',
25: 'ㅌ',
26: 'ㅍ',
27: 'ㅎ'
}
self.dictHanLetterRomanized = {
0: '', 1: 'g', 2: 'gg', 3: 'gs',
4: 'n', 5: 'nz', 6: 'nh',
7: 'd', 8: 'dd',
9: 'l', 10: 'lg', 11: 'lm', 12: 'lb', 13: 'ls', 14: 'lt', 15: 'lp', 16: 'lh',
17: 'm',
18: 'b', 19: 'bb', 20: 'bs',
21: 's', 22: 'ss',
23: 'j', # 'ㅇ',
24: 'z', 25: 'zz',
26: 'c',
27: 'k',
28: 't',
29: 'p',
30: 'h',
31: 'a', # 'ㅏ'
32: 'ai', # 'ㅐ'
33: 'ya', # 'ㅑ'
34: 'yai', # 'ㅒ'
35: 'e', # 'ㅓ'
36: 'ei', # 'ㅔ'
37: 'ye', # 'ㅕ'
38: 'yei', # 'ㅖ'
39: 'o', # 'ㅗ'
40: 'oa', # 'ㅘ'
41: 'oai', # 'ㅙ'
42: 'oi', # 'ㅚ'
43: 'yo', # 'ㅛ'
44: 'u', # 'ㅜ'
45: 'ue', # 'ㅝ'
46: 'uei', # 'ㅞ'
47: 'ui', # 'ㅟ'
48: 'yu', # 'ㅠ'
49: 'w', # 'ㅡ'
50: 'wi', # 'ㅢ'
51: 'i' # 'ㅣ'
}
# 초성 19자: ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ
self.dictFirstLetterRomanized = {
# j = 'ㅇ'
0: 'g', # 'ㄱ',
1: 'gg', # 'ㄲ',
2: 'n', # 'ㄴ',
3: 'd', # 'ㄷ',
4: 'dd', # 'ㄸ',
5: 'l', # 'ㄹ',
6: 'm', # 'ㅁ',
7: 'b', # 'ㅂ',
8: 'bb', # 'ㅃ',
9: 's', # 'ㅅ',
10: 'ss', # 'ㅆ',
11: 'j', # 'ㅇ',
12: 'z', # 'ㅈ',
13: 'zz', # 'ㅉ',
14: 'c', # 'ㅊ',
15: 'k', # 'ㅋ',
16: 't', # 'ㅌ',
17: 'p', # 'ㅍ',
18: 'h', # 'ㅎ'
}
# 중성 21자: ㅏ,ㅐ,ㅑ,ㅒ, ㅓ,ㅔ,ㅕ,ㅖ, ㅗ,ㅘ,ㅙ,ㅚ, ㅛ, ㅜ,ㅝ,ㅞ,ㅟ, ㅠ, ㅡ,ㅢ,ㅣ
self.dictMiddleLetterRomanized = {
# e = 'ㅓ', w = 'ㅡ'
0: 'a', # 'ㅏ'
1: 'ai', # 'ㅐ'
2: 'ya', # 'ㅑ'
3: 'yai', # 'ㅒ'
4: 'e', # 'ㅓ'
5: 'ei', # 'ㅔ'
6: 'ye', # 'ㅕ'
7: 'yei', # 'ㅖ'
8: 'o', # 'ㅗ'
9: 'oa', # 'ㅘ'
10: 'oai', # 'ㅙ'
11: 'oi', # 'ㅚ'
12: 'yo', # 'ㅛ'
13: 'u', # 'ㅜ'
14: 'ue', # 'ㅝ'
15: 'uei', # 'ㅞ'
16: 'ui', # 'ㅟ'
17: 'yu', # 'ㅠ'
18: 'w', # 'ㅡ'
19: 'wi', # 'ㅢ'
20: 'i' # 'ㅣ'
}
# 종성이 28자: '','ㄱ','ㄲ','ㄳ','ㄴ','ㄵ','ㄶ','ㄷ',
# 'ㄹ','ㄺ','ㄻ','ㄼ','ㄽ','ㄾ','ㄿ','ㅀ',
# 'ㅁ','ㅂ','ㅄ','ㅅ','ㅆ','ㅇ','ㅈ','ㅊ','ㅋ','ㅌ','ㅍ','ㅎ'
self.dictLastLetterRomanized = {
# '' = 받침없음, j = 'ㅇ',
0: '', 1: 'g', 2: 'gg', 3: 'gs',
4: 'n', 5: 'nz', 6: 'nh',
7: 'd',
8: 'l', 9: 'lg', 10: 'lm', 11: 'lb', 12: 'ls', 13: 'lt', 14: 'lp', 15: 'lh',
16: 'm',
17: 'b', 18: 'bs',
19: 's', 20: 'ss',
21: 'j', # 'ㅇ',
22: 'z',
23: 'c',
24: 'k',
25: 't',
26: 'p',
27: 'h'
}
# int('가'.encode('utf-16be').hex(), 16) # 44032
# '가'.encode('utf-16be') # unicode b'\xac\x00'
# '가'.encode('utf-8') # utf-8 b'\xea\xb0\x80'
한글 romanization 전체 코드
class Han2Eng:
def __init__(self):
self.flagHan = False # 최초 문자가 로마자(알파벳)이라 간주함.
self.flagSwitch = False # 단어 중에서 이전 문자와 현재 문자의 종류(알파벳 또는 한글)가 바뀌지 않음
# unicode table은 연속되는 순서로 배열된 테이블이다.
# utf-8은 연속되지 않는 변환 숫자이다.
# 초성 19자: ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ
self.dictFirstLetter = {
0: 'ㄱ',
1: 'ㄲ',
2: 'ㄴ',
3: 'ㄷ',
4: 'ㄸ',
5: 'ㄹ',
6: 'ㅁ',
7: 'ㅂ',
8: 'ㅃ',
9: 'ㅅ',
10: 'ㅆ',
11: 'ㅇ',
12: 'ㅈ',
13: 'ㅉ',
14: 'ㅊ',
15: 'ㅋ',
16: 'ㅌ',
17: 'ㅍ',
18: 'ㅎ'
}
# 중성 21자:
# ㅏ, ㅐ, ㅑ, ㅒ, ㅓ, ㅔ, ㅕ, ㅖ,
# ㅗ, ㅘ, ㅙ, ㅚ, ㅛ,
# ㅜ, ㅝ , ㅞ, ㅟ, ㅠ,
# ㅡ, ㅢ, ㅣ
self.dictMiddleLetter = {
0: 'ㅏ', 1: 'ㅐ', 2: 'ㅑ', 3: 'ㅒ',
4: 'ㅓ', 5: 'ㅔ', 6: 'ㅕ', 7: 'ㅖ',
8: 'ㅗ', 9: 'ㅘ', 10: 'ㅙ', 11: 'ㅚ',
12: 'ㅛ',
13: 'ㅜ', 14: 'ㅝ', 15: 'ㅞ', 16: 'ㅟ',
17: 'ㅠ',
18: 'ㅡ', 19: 'ㅢ', 20: 'ㅣ'
}
# 종성이 28자: '','ㄱ','ㄲ','ㄳ','ㄴ','ㄵ','ㄶ','ㄷ',
# 'ㄹ','ㄺ','ㄻ','ㄼ','ㄽ','ㄾ','ㄿ','ㅀ',
# 'ㅁ','ㅂ','ㅄ','ㅅ','ㅆ','ㅇ','ㅈ','ㅊ','ㅋ','ㅌ','ㅍ','ㅎ'
self.dictLastLetter = {
0: '', 1: 'ㄱ', 2: 'ㄲ', 3: 'ㄳ',
4: 'ㄴ', 5: 'ㄵ', 6: 'ㄶ',
7: 'ㄷ',
8: 'ㄹ', 9: 'ㄺ', 10: 'ㄻ', 11: 'ㄼ', 12: 'ㄽ', 13: 'ㄾ', 14: 'ㄿ', 15: 'ㅀ',
16: 'ㅁ',
17: 'ㅂ', 18: 'ㅄ',
19: 'ㅅ', 20: 'ㅆ',
21: 'ㅇ',
22: 'ㅈ',
23: 'ㅊ',
24: 'ㅋ',
25: 'ㅌ',
26: 'ㅍ',
27: 'ㅎ'
}
self.dictHanLetterRomanized = {
0: '', 1: 'g', 2: 'gg', 3: 'gs',
4: 'n', 5: 'nz', 6: 'nh',
7: 'd', 8: 'dd',
9: 'l', 10: 'lg', 11: 'lm', 12: 'lb', 13: 'ls', 14: 'lt', 15: 'lp', 16: 'lh',
17: 'm',
18: 'b', 19: 'bb', 20: 'bs',
21: 's', 22: 'ss',
23: 'j', # 'ㅇ',
24: 'z', 25: 'zz',
26: 'c',
27: 'k',
28: 't',
29: 'p',
30: 'h',
31: 'a', # 'ㅏ'
32: 'ai', # 'ㅐ'
33: 'ya', # 'ㅑ'
34: 'yai', # 'ㅒ'
35: 'e', # 'ㅓ'
36: 'ei', # 'ㅔ'
37: 'ye', # 'ㅕ'
38: 'yei', # 'ㅖ'
39: 'o', # 'ㅗ'
40: 'oa', # 'ㅘ'
41: 'oai', # 'ㅙ'
42: 'oi', # 'ㅚ'
43: 'yo', # 'ㅛ'
44: 'u', # 'ㅜ'
45: 'ue', # 'ㅝ'
46: 'uei', # 'ㅞ'
47: 'ui', # 'ㅟ'
48: 'yu', # 'ㅠ'
49: 'w', # 'ㅡ'
50: 'wi', # 'ㅢ'
51: 'i' # 'ㅣ'
}
# 초성 19자: ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ
self.dictFirstLetterRomanized = {
# j = 'ㅇ'
0: 'g', # 'ㄱ',
1: 'gg', # 'ㄲ',
2: 'n', # 'ㄴ',
3: 'd', # 'ㄷ',
4: 'dd', # 'ㄸ',
5: 'l', # 'ㄹ',
6: 'm', # 'ㅁ',
7: 'b', # 'ㅂ',
8: 'bb', # 'ㅃ',
9: 's', # 'ㅅ',
10: 'ss', # 'ㅆ',
11: 'j', # 'ㅇ',
12: 'z', # 'ㅈ',
13: 'zz', # 'ㅉ',
14: 'c', # 'ㅊ',
15: 'k', # 'ㅋ',
16: 't', # 'ㅌ',
17: 'p', # 'ㅍ',
18: 'h', # 'ㅎ'
}
# 중성 21자: ㅏ,ㅐ,ㅑ,ㅒ, ㅓ,ㅔ,ㅕ,ㅖ, ㅗ,ㅘ,ㅙ,ㅚ, ㅛ, ㅜ,ㅝ,ㅞ,ㅟ, ㅠ, ㅡ,ㅢ,ㅣ
self.dictMiddleLetterRomanized = {
# e = 'ㅓ', w = 'ㅡ'
0: 'a', # 'ㅏ'
1: 'ai', # 'ㅐ'
2: 'ya', # 'ㅑ'
3: 'yai', # 'ㅒ'
4: 'e', # 'ㅓ'
5: 'ei', # 'ㅔ'
6: 'ye', # 'ㅕ'
7: 'yei', # 'ㅖ'
8: 'o', # 'ㅗ'
9: 'oa', # 'ㅘ'
10: 'oai', # 'ㅙ'
11: 'oi', # 'ㅚ'
12: 'yo', # 'ㅛ'
13: 'u', # 'ㅜ'
14: 'ue', # 'ㅝ'
15: 'uei', # 'ㅞ'
16: 'ui', # 'ㅟ'
17: 'yu', # 'ㅠ'
18: 'w', # 'ㅡ'
19: 'wi', # 'ㅢ'
20: 'i' # 'ㅣ'
}
# 종성이 28자: '','ㄱ','ㄲ','ㄳ','ㄴ','ㄵ','ㄶ','ㄷ',
# 'ㄹ','ㄺ','ㄻ','ㄼ','ㄽ','ㄾ','ㄿ','ㅀ',
# 'ㅁ','ㅂ','ㅄ','ㅅ','ㅆ','ㅇ','ㅈ','ㅊ','ㅋ','ㅌ','ㅍ','ㅎ'
self.dictLastLetterRomanized = {
# '' = 받침없음, j = 'ㅇ',
0: '', 1: 'g', 2: 'gg', 3: 'gs',
4: 'n', 5: 'nz', 6: 'nh',
7: 'd',
8: 'l', 9: 'lg', 10: 'lm', 11: 'lb', 12: 'ls', 13: 'lt', 14: 'lp', 15: 'lh',
16: 'm',
17: 'b', 18: 'bs',
19: 's', 20: 'ss',
21: 'j', # 'ㅇ',
22: 'z',
23: 'c',
24: 'k',
25: 't',
26: 'p',
27: 'h'
}
# int('가'.encode('utf-16be').hex(), 16) # 44032
# '가'.encode('utf-16be') # unicode b'\xac\x00'
# '가'.encode('utf-8') # utf-8 b'\xea\xb0\x80'
def lookupHanChar(self, aHanChar='깐'):
# pos = int(aHanChar.encode('utf-16be').hex(), 16)
# base = int('가'.encode('utf-16be').hex(), 16) # 한글 시작 직전 위치,
pos = ord(aHanChar)
if pos >= 12593 and pos <= 12643: # 자모
iAtLast = pos - ord('ㄱ') + 1 # 제일 첫번째는 무음
iAtFirst = -1 # 한글 자모 표시
iAtMiddle = -1
if self.flagHan:
self.flagSwitch = False
insertChar = ''
else:
self.flagSwitch = True
self.flagHan = True
insertChar = ' '
elif pos >= ord('가') and pos <= ord('힣'): # 한글글자
ith = pos - ord('가')
iAtFirst = ith // (28 * 21)
iAtMiddle = ith % (28 * 21) // 28
iAtLast = ith % (28 * 21) % 28 % 28 # iAtLast = ith % 28
if self.flagHan:
self.flagSwitch = False
insertChar = ''
else:
self.flagSwitch = True
self.flagHan = True
insertChar = ' '
else:
iAtFirst = -2 # 한글이 아님 표시
iAtMiddle = -2
iAtLast = -2
if self.flagHan:
self.flagSwitch = True
self.flagHan = False
insertChar = ' '
else:
self.flagSwitch = False
insertChar = ''
print(iAtFirst, iAtMiddle, iAtLast)
return iAtFirst, iAtMiddle, iAtLast, insertChar
def aHanChar2aEngStr(self, aHanChar):
iAtFirst, iAtMiddle, iAtLast, insertChar = self.lookupHanChar(aHanChar)
if iAtFirst == -2:
aEngStr = insertChar + aHanChar
elif iAtFirst == -1:
aEngStr = insertChar + self.dictHanLetterRomanized[iAtLast] + '_' # '_' 한글글자 구분 가독성을 위해서 넣음
else:
aEngStr = (
insertChar
+ self.dictFirstLetterRomanized[iAtFirst]
+ self.dictMiddleLetterRomanized[iAtMiddle]
+ self.dictLastLetterRomanized[iAtLast]
+ '_'
)
print(aHanChar, aEngStr)
return aEngStr
def aHanStr2aEngStr(self, aHanStr):
aEngStr = ''
for c in aHanStr:
aEngStr += self.aHanChar2aEngStr(c)
return aEngStr
if __name__ == "__main__":
H2E = Han2Eng()
# 초성 19자: ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ
# 중성 21자: ㅏ,ㅐ,ㅑ,ㅒ, ㅓ,ㅔ,ㅕ,ㅖ, ㅗ,ㅘ,ㅙ,ㅚ, ㅛ, ㅜ,ㅝ,ㅞ,ㅟ, ㅠ, ㅡ,ㅢ,ㅣ
# 종성이 28자: '','ㄱ','ㄲ','ㄳ','ㄴ','ㄵ','ㄶ','ㄷ',
# 'ㄹ','ㄺ','ㄻ','ㄼ','ㄽ','ㄾ','ㄿ','ㅀ',
# 'ㅁ','ㅂ','ㅄ','ㅅ','ㅆ','ㅇ','ㅈ','ㅊ','ㅋ','ㅌ','ㅍ','ㅎ'
aHanStr = 'aㅁㅋa가깩냒댻떤렍멶볟뽈솱쐚욃죬쭕춾퀧튐퓹흢긧깠냉댲떛렄멭볖뼿'
print(aHanStr)
aEngStr = H2E.aHanStr2aEngStr(aHanStr)
print(aEngStr)
'Pythonian' 카테고리의 다른 글
다양한 날짜 포멧 문자열을 날짜 datetime 포멧으로 변환하기 (0) | 2022.05.20 |
---|---|
파이썬에서 일정 간격 이내 지점 삭제하기 (0) | 2022.01.20 |
그림 창은 열리는데 그림이 안보인다 (0) | 2022.01.06 |
엑셀파일 읽기 방법 (0) | 2021.12.31 |
파이썬 리스트 곱하기 대 넘파이 배열 곱하기 (0) | 2021.12.26 |
댓글