문자열 변환하기
문자열을 변환하는 작업은 한글로 변환하면서 해당 문자가 초성인지, 중성인지, 종성인지 판단하는 것도 중요하다.
이를 구분하기 위해 5가지로 분류할 수 있는데,
자음만 있는 경우 -> c
초성인 경우 -> l
모음인 경우 -> v
종성인 경우 -> t
로 지정해주고 나머지는 그대로 값을 넣어준다.
def MakeHangeul(words: str) -> str:
# ----- 중략 -----
# 입력 받은 값을 저장하고 단어 조합하기 위한 값을 저장하는 변수
result, result_state = "", []
idx, n = 0, len(words)
# 입력 받은 것을 index에 따라 저장을
# 초성: l, 모음: v, 종성: t, 자음만: c 로 분류하며 저장
while idx < n:
word = words[idx]
# 기호가 있는 경우 그냥 저장
if word in "0123456789`~!@#$%^&*()_+-=[]{};':\"\\|,./<>? ":
result += word
result_state.append(word)
이렇게 result와 result_state에 값과 상태를 저장하는데 영어 알파벳이 아닌 경우, 그냥 저장을 진행한다.
그게 아닌 경우에는 아래와 같이 작업을 한다.
# 키보드 누른 값이 변환 가능한 것이면 조건문 실행
if keyval[word] != 0:
ch = keyval[word]
# 자음 입력 받았을 때
if ch < 0x314f:
# 이중 자음 받침일 경우
if result_state and (ord(result[-1]), ch) in double_jong.keys():
jong = double_jong[(ord(result[-1]), ch)]
result = result[:-1] + jong
idx += 1
continue
# 현재 이전에 입력 받은 문자가 모음이면
# 종성(t) 추가, 아니면 단자음(c) 추가
elif result_state and result_state[-1] == "v":
result_state.append("t")
else:
result_state.append("c")
# 모음 입력 받았을 때
else:
if result_state:
# 종성 값이 있는 경우
if result[-1] in double_jong_num.keys():
jong = double_jong_num[result[-1]]
result = result[:-1] + jong + chr(ch)
result_state += ["l", "v"]
idx += 1
continue
# 모음이 들어 왔을 때, 앞의 단자음을 초성으로 변환
elif result_state[-1] in ["c", "t"]:
result_state[-1] = "l"
# 이중 종성 이 들어왔을 경우, 변환
elif (ord(result[-1]), ch) in double_jung.keys():
jung = double_jung[(ord(result[-1]), ch)]
result = result[:-1] + jung
idx += 1
continue
result_state.append("v")
result += chr(ch)
이제 자음과 모음을 입력 받았을 경우로 나뉘는데,
자음을 받았을 경우,
빈 문자열이거나 특수 기호가 마지막에 들어 왔으면 result에 그냥 입력하고 result_state에는 "c"를 추가한다.
빈 문자열이 아니고 앞의 문자와 조합했을 때, 이중 종성이 만들어지는 것이면 이중 종성으로 만들어주고 result_state는 따로 추가해주지 않는다.
마지막으로 입력받은 문자가 모음인 경우에는 result에 자음을 추가하고 종성인 "t"를 추가해주는 식으로 처리한다.
여기서 핵심이라고 생각되는 것은 문자를 추가하는 데 있어 앞의 문자를 보고 이것이 초성 / 종성 / 단자음을 판단하는 것이 핵심이라고 생각된다.
모음을 받았을 경우,
모음 같은 경우는 자신에 대한 변화는 없지만, 앞/뒤 문자에 대한 변화를 주는 데 초점을 맞췃다.
마지막에 입력받은 문자가 종성이면 result_state를 초성인 "l"로 변환해주고 중성인 "v"를 추가해준다.
마지막에 입력받은 문자가 이중 자음인 경우에는 해당 문자를 분리 해주고 result_state에는 초성인 "l"과 모음인 "v"를 추가해준다.
이렇게 작업 해주고 마지막에 공백을 추가하여 완전히 출력될 수 있도록 만들어 준다.
전체 코드를 보면,
def MakeHangeul(words: str) -> str:
# 영어를 한글로 변환하기 위한 dict
# ------------------------------ start ------------------------------
keyval = {
"A": 0, "B": 0, "C": 0, "D": 0, "E": 0x3138,
"F": 0, "G": 0, "H": 0, "I": 0, "J": 0, "K": 0,
"L": 0, "M": 0, "N": 0, "O": 0x3152, "P": 0x3156,
"Q": 0x3143, "R": 0x3132, "S": 0, "T": 0x3146,
"U": 0, "V": 0, "W": 0x3149, "X": 0, "Y": 0, "Z": 0,
"a": 0x3141, "b": 0x3160, "c": 0x314a, "d": 0x3147,
"e": 0x3137, "f": 0x3139, "g": 0x314e, "h": 0x3157,
"i": 0x3151, "j": 0x3153, "k": 0x314f, "l": 0x3163,
"m": 0x3161, "n": 0x315c, "o": 0x3150, "p": 0x3154,
"q": 0x3142, "r": 0x3131, "s": 0x3134, "t": 0x3145,
"u": 0x3155, "v": 0x314d, "w": 0x3148, "x": 0x314c,
"y": 0x315b, "z": 0x314b
}
double_jong: dict = {
(12593, 12613): chr(0x3133), (12596, 12616): chr(0x3135), # ㄳ ㄵ
(12596, 12622): chr(0x3136), (12601, 12593): chr(0x313a), # ㄶ ㄺ
(12601, 12609): chr(0x313b), (12601, 12610): chr(0x313c), # ㄻ ㄼ
(12601, 12613): chr(0x313d), (12601, 12620): chr(0x313e), # ㄽ ㄾ
(12601, 12621): chr(0x313f), (12601, 12622): chr(0x3140), # ㄿ ㅀ
(12610, 12613): chr(0x3144) # ㅄ
}
double_jong_num = {
"ㄳ": "ㄱㅅ", "ㄵ": "ㄴㅈ",
"ㄶ": "ㄴㅎ", "ㄺ": "ㄹㄱ",
"ㄻ": "ㄹㅁ", "ㄼ": "ㄹㅂ",
"ㄽ": "ㄹㅅ", "ㄾ": "ㄹㅌ",
"ㄿ": "ㄹㅍ", "ㅀ": "ㄹㅎ",
"ㅄ": "ㅂㅅ"
}
double_jung = {
# ㅘ ㅙ ㅚ ㅝ ㅞ ㅟ ㅢ
(12631, 12623): chr(12633), (12631, 12624): chr(12632),
(12631, 12643): chr(12634), (12636, 12627): chr(12637),
(12636, 12628): chr(12638), (12636, 12643): chr(12639),
(12641, 12643): chr(12642)
}
# ------------------------------ end ------------------------------
# 입력 받은 값을 저장하고 단어 조합하기 위한 값을 저장하는 변수
result, result_state = "", []
idx, n = 0, len(words)
# 입력 받은 것을 index에 따라 저장을
# 초성: l, 모음: v, 종성: t, 자음만: c 로 분류하며 저장
while idx < n:
word = words[idx]
# 기호가 있는 경우 그냥 저장
if word in "0123456789`~!@#$%^&*()_+-=[]{};':\"\\|,./<>? ":
result += word
result_state.append(word)
else:
# 키보드 누른 값이 변환 가능한 것이면 조건문 실행
if keyval[word] != 0:
ch = keyval[word]
# 자음 입력 받았을 때
if ch < 0x314f:
# 이중 자음 받침일 경우
if result_state and (ord(result[-1]), ch) in double_jong.keys():
jong = double_jong[(ord(result[-1]), ch)]
result = result[:-1] + jong
idx += 1
continue
# 현재 이전에 입력 받은 문자가 모음이면
# 종성(t) 추가, 아니면 단자음(c) 추가
elif result_state and result_state[-1] == "v":
result_state.append("t")
else:
result_state.append("c")
# 모음 입력 받았을 때
else:
if result_state:
# 종성 값이 있는 경우
if result[-1] in double_jong_num.keys():
jong = double_jong_num[result[-1]]
result = result[:-1] + jong + chr(ch)
result_state += ["l", "v"]
idx += 1
continue
# 모음이 들어 왔을 때, 앞의 단자음을 초성으로 변환
elif result_state[-1] in ["c", "t"]:
result_state[-1] = "l"
# 이중 종성 이 들어왔을 경우, 변환
elif (ord(result[-1]), ch) in double_jung.keys():
jung = double_jung[(ord(result[-1]), ch)]
result = result[:-1] + jung
idx += 1
continue
result_state.append("v")
result += chr(ch)
idx += 1
# 한 단어만 입력되었을 때, 출력이 안되는 케이스 방지를 위해 설정
result_state.append('')
result += ' '
return MappingHangeul(result, result_state)
이제 변환된 문자열을 MappingHangeul 함수를 통해 변환해주면 된다.
'IT 톺아보기 > 이런저런 공부' 카테고리의 다른 글
CAN 통신 (1) | 2023.04.17 |
---|---|
멀티 프로세스(Multi Process)란? (0) | 2023.02.01 |
한글 오토마타 만들기 - 2 (0) | 2023.01.18 |
한글 오토마타 만들기 - 1 (1) | 2023.01.18 |
인코딩이란 - 2. base64 Encoding / Decoding (0) | 2023.01.18 |