유니코드 정규화란?

wldbs._.·2025년 9월 22일
0

SW

목록 보기
6/8
post-thumbnail

RAG를 진행하며, 문자의 통일 및 비교에 대한 내용을 많이 접하였다.
그 중에서 유니코드 정규화라는 개념이 중요시되어, 이를 간략하게 정리하고자 한다.


유니코드란?

유니코드(Unicode)는 전 세계의 모든 문자와 기호를 컴퓨터에서 일관되게 표현하기 위해 만든 국제 표준 문자 인코딩 체계이다.
쉽게 말해, “문자를 숫자로 약속하는 규칙”이다.

⭐ 눈으로 보면 똑같이 보이지만, 내부적으로는 서로 다른 코드 포인트 조합으로 표현될 수 있는 문자를 하나의 표준 형태로 맞추는 과정


✨ 왜 필요한가?

  • 예전에는 각 나라·회사마다 자체적으로 문자 인코딩 방식을 만들었다.
    • 한국: EUC-KR, CP949
    • 일본: Shift-JIS
    • 서양: ISO-8859-1, ASCII
  • 이렇게 제각각 쓰다 보니 같은 문서라도 다른 환경에서는 글자가 깨져 보이는 ‘문자 깨짐(꺠짐)’ 문제가 많이 발생한다.

유니코드에서는 같은 글자라도 여러 방식으로 표현이 가능하다.

✅ 예를 들어:

  • "é" (에 악센트)
    1. 단일 코드 포인트: U+00E9 (é)
    2. 조합형: U+0065 (e) + U+0301 (´)

겉보기에는 똑같이 "é"지만, 메모리 속 이진 값은 달라서

문자 비교("é" == "é")나 문자열 검색에서 문제가 생길 수 있다.

유니코드는 이런 문제를 해결하기 위해 “하나의 전 세계 공통 문자 코드 체계”를 정의했다.


🧩 핵심 개념

  1. 코드 포인트(Code Point)
    • 각 문자를 표현하는 고유한 번호.
    • 예:
      • A → U+0041
      • 가 → U+AC00
      • 😀 → U+1F600
  2. 인코딩 방식(UTF-8, UTF-16, UTF-32 등)
    • 코드 포인트를 실제로 저장하거나 전송할 때, 바이트 단위로 변환하는 방법.
    • UTF-8은 웹에서 가장 많이 쓰이는 방식으로, 영어는 1바이트, 한글은 3바이트로 표현된다.
  3. 문자 범위(Planes)
    • 유니코드에는 100만 개 이상의 코드 포인트가 예약되어 있고, 이를 여러 “평면(plane)”으로 나눠 관리한다.
    • 기본 다국어 평면(BMP): U+0000 ~ U+FFFF (한글, 한자, 알파벳 등 대부분 포함)
    • 보조 평면: 이모지, 고대 문자 등 포함

🌍 실제 예시

  • "안녕" → UTF-8 인코딩 결과:
    • EC 95 88
    • EB 85 95
  • 같은 문자가 어디서든 똑같이 표시될 수 있는 이유가 여기에 있다.

👉 정리하면, 유니코드 = 문자에 부여한 국제 공용 번호 체계,

그리고 UTF-8/16 같은 방식 = 그 번호를 실제 컴퓨터에서 저장·전송하는 방법.


🧩 정규화 방식의 종류

유니코드 표준에서는 크게 4가지 정규화 형식을 정의한다:

방식설명예시
NFC (Normalization Form C)조합할 수 있는 문자는 하나로 합침(합성)e + ´ → é
NFD (Normalization Form D)모든 문자를 가능한 한 분리(분해)é → e + ´
NFKC (Compatibility Composition)모양만 다른 호환 문자를 표준 문자로 합성① → 1
NFKD (Compatibility Decomposition)모양만 다른 문자를 분해 후 표준화① → 1

🌍 실제 사례

import unicodedata

s1 = "é"               # 단일 코드포인트 U+00E9
s2 = "e\u0301"         # 조합형: U+0065 + U+0301

print(s1 == s2)  # False (겉보기는 같지만 내부 코드 다름)

# 정규화 후 비교
print(unicodedata.normalize("NFC", s1) == unicodedata.normalize("NFC", s2))  # True

RAG를 구현할때, 아래의 함수를 빈번하게 활용했다.

def normalize_category_text(text: str) -> str:
    """카테고리 텍스트 정규화 함수
    - ⭐ 추가: 같은 한글도 자음/모음 결합 방식이 상이할 수 있음 => 정규화 필요
    Args:
        text: 정규화할 카테고리 텍스트
        
    Returns:
        정규화된 카테고리 텍스트
    """
    if not text:
        return text
        
    # 1. 유니코드 정규화 (NFC - 완성형으로 통일)
    normalized = unicodedata.normalize('NFC', text)
    
    # 2. 공백을 언더바로 통일
    normalized = normalized.replace(' ', '_')
    
    # 3. 연속된 언더바를 하나로 통합
    normalized = re.sub(r'_+', '_', normalized)
    
    # 4. 앞뒤 공백/언더바 제거
    normalized = normalized.strip('_ ')
    
    return normalized

✅ 정리하면:

정규화 = 서로 다른 유니코드 표현을 같은 규칙(NFC, NFD 등)에 맞춰 ‘동일한 코드열’로 통일하는 과정이다.

profile
공부 기록용 24.08.05~ #LLM #RAG

0개의 댓글