Cấp bậc tác giả:

TRAINING

Chuẩn hóa kiểu gõ dấu tiếng Việt

Được viết bởi webmaster ngày 09/08/2020 lúc 05:36 PM
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).
  • 0
  • 6955

Chuẩn hóa kiểu gõ dấu tiếng Việt

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é.

Nguồn bài viết: Sưu tầm

BÌNH LUẬN BÀI VIẾT

Bài viết mới nhất

LIKE BOX

Bài viết được xem nhiều nhất

HỌC HTML