Hiện nay, tiếng Việt có 2 kiểu gõ dấu khác nhau. Chúng lần lượt có tên là kiểu mới (ex: oà, uý) và kiểu cũ (ex: òa, úy). Chi tiết sự khác nhau bạn có thể
xem tại đây.
Do đó, các bộ gõ tiếng Việt phổ biến hiện nay cũng cho phép tùy chỉnh chọn một trong hai cách gõ dấu kể trên. Dẫn đến các từ giống nhau nhưng lại có cách viết khác nhau khi chúng ta sử dụng dữ liệu văn bản vào các bài toán học máy. Do đó, việc cần làm là đưa chúng về một bộ gõ tiêu chuẩn.
Theo kinh nghiệm bản thân cũng như các văn bản, tài liệu mình tiếp xúc hàng ngày thì kiểu gõ cũ vẫn chiếm ưu thế tuyệt đối. Và mặc định các bộ gõ tiếng Việt cũng dùng kiểu cũ luôn.
Cách khắc phục: Đưa về kiểu gõ dấu cũ đối với các từ dùng kiểu gõ mới.
Script python dưới đây cung cấp cho bạn khả năng chuẩn hóa kiểu gõ về kiểu cũ, đồng thời không làm thay đổi cấu trúc dữ liệu gốc (giữ nguyên hoa thường, dấu ngắt câu,…).
def chuan_hoa_dau_tu_tieng_viet(word):
if not is_valid_vietnam_word(word):
return word
chars = list(word)
dau_cau = 0
nguyen_am_index = []
qu_or_gi = False
for index, char in enumerate(chars):
x, y = nguyen_am_to_ids.get(char, (-1, -1))
if x == -1:
continue
elif x == 9: # check qu
if index != 0 and chars[index - 1] == 'q':
chars[index] = 'u'
qu_or_gi = True
elif x == 5: # check gi
if index != 0 and chars[index - 1] == 'g':
chars[index] = 'i'
qu_or_gi = True
if y != 0:
dau_cau = y
chars[index] = bang_nguyen_am[x][0]
if not qu_or_gi or index != 1:
nguyen_am_index.append(index)
if len(nguyen_am_index) < 2:
if qu_or_gi:
if len(chars) == 2:
x, y = nguyen_am_to_ids.get(chars[1])
chars[1] = bang_nguyen_am[x][dau_cau]
else:
x, y = nguyen_am_to_ids.get(chars[2], (-1, -1))
if x != -1:
chars[2] = bang_nguyen_am[x][dau_cau]
else:
chars[1] = bang_nguyen_am[5][dau_cau] if chars[1] == 'i' else bang_nguyen_am[9][dau_cau]
return ''.join(chars)
return word
for index in nguyen_am_index:
x, y = nguyen_am_to_ids[chars[index]]
if x == 4 or x == 8: # ê, ơ
chars[index] = bang_nguyen_am[x][dau_cau]
# for index2 in nguyen_am_index:
# if index2 != index:
# x, y = nguyen_am_to_ids[chars[index]]
# chars[index2] = bang_nguyen_am[x][0]
return ''.join(chars)
if len(nguyen_am_index) == 2:
if nguyen_am_index[-1] == len(chars) - 1:
x, y = nguyen_am_to_ids[chars[nguyen_am_index[0]]]
chars[nguyen_am_index[0]] = bang_nguyen_am[x][dau_cau]
# x, y = nguyen_am_to_ids[chars[nguyen_am_index[1]]]
# chars[nguyen_am_index[1]] = bang_nguyen_am[x][0]
else:
# x, y = nguyen_am_to_ids[chars[nguyen_am_index[0]]]
# chars[nguyen_am_index[0]] = bang_nguyen_am[x][0]
x, y = nguyen_am_to_ids[chars[nguyen_am_index[1]]]
chars[nguyen_am_index[1]] = bang_nguyen_am[x][dau_cau]
else:
# x, y = nguyen_am_to_ids[chars[nguyen_am_index[0]]]
# chars[nguyen_am_index[0]] = bang_nguyen_am[x][0]
x, y = nguyen_am_to_ids[chars[nguyen_am_index[1]]]
chars[nguyen_am_index[1]] = bang_nguyen_am[x][dau_cau]
# x, y = nguyen_am_to_ids[chars[nguyen_am_index[2]]]
# chars[nguyen_am_index[2]] = bang_nguyen_am[x][0]
return ''.join(chars)
def is_valid_vietnam_word(word):
chars = list(word)
nguyen_am_index = -1
for index, char in enumerate(chars):
x, y = nguyen_am_to_ids.get(char, (-1, -1))
if x != -1:
if nguyen_am_index == -1:
nguyen_am_index = index
else:
if index - nguyen_am_index != 1:
return False
nguyen_am_index = index
return True
def chuan_hoa_dau_cau_tieng_viet(sentence):
"""
Chuyển câu tiếng việt về chuẩn gõ dấu kiểu cũ.
:param sentence:
:return:
"""
sentence = sentence.lower()
words = sentence.split()
for index, word in enumerate(words):
cw = re.sub(r'(^\p{P}*)([p{L}.]*\p{L}+)(\p{P}*$)', r'\1/\2/\3', word).split('/')
# print(cw)
if len(cw) == 3:
cw[1] = chuan_hoa_dau_tu_tieng_viet(cw[1])
words[index] = ''.join(cw)
return ' '.join(words)
"""
End section: Chuyển câu văn về cách gõ dấu kiểu cũ: dùng òa úy thay oà uý
Xem tại đây: https://vi.wikipedia.org/wiki/Quy_tắc_đặt_dấu_thanh_trong_chữ_quốc_ngữ
"""
if __name__ == '__main__':
print(chuan_hoa_dau_cau_tieng_viet('anh hoà, đang làm.. gì'))
Ngoài ra, script chuẩn hóa (bảng mã, cách gõ dấu) còn có phiên bản ngôn ngữ Java, bạn có thể xem đầy đủ cả 2 phiên bản Java và Python
tại đây.
Trên đây là một số kỹ thuật xử lý tiếng Việt trong Python do bản thân mình ghi chép lại. Nếu bạn có những kỹ thuật khác thì đừng ngại chia sẻ dưới mục thảo luận của bài viết nhé.