티스토리 뷰

00. TL;DR

  • String.prototype.normalize() 메서드는 문자열의 유니코드 정규화를 수행하며, 서로 다른 유니코드 조합 방식으로 표현된 동일 문자를 일관된 형식으로 변환합니다.
  • normalize 메서드를 이용하면 문자열 비교, 검색, 파일명 호환성 및 다국어 처리를 쉽게 할 수 있습니다.
  • 정규화 방식에는 NFC, NFD, NFKC, NFKD가 존재합니다.

01. String.prototype.normalize()란?

normalize() 메서드는 문자열을 유니코드 정규화(Unicode Normalization)하는 기능을 합니다.

유니코드에서는 동일한 의미의 문자가 여러 방식으로 표현될 수 있으므로, 이를 표준화하여 비교나 검색 등에서 정확한 결과를 얻기 위해 사용됩니다.


02. 유니코드 정규화가 필요한 이유

유니코드는 하나의 문자를 다양한 방식으로 표현할 수 있습니다.

예를 들어:

  • é (e + ´)
    • "\u0065\u0301" → "e"와 조합 문자인 "́"로 구성
    • "\u00E9" → 단일 문자 "é"
  • 한글의 경우
    • "가" → 초성 "ᄀ"와 중성 "ᅡ"가 분해된 형태
    • "가" → 완성형 "가"

이처럼 같은 의미를 가지지만 내부적으로 다른 유니코드 값으로 표현된 문자열을 동일하게 취급하기 위해 정규화가 필요합니다.


03. normalize()의 동작 방식

normalize()는 네 가지 정규화 방식을 지원합니다:

정규화 방식 설명
NFC (기본값) 조합 가능한 문자를 하나의 문자로 합칩니다. (Normalization Form Composed)
NFD 문자를 가능한 한 분해합니다. (Normalization Form Decomposed)
NFKC NFC와 유사하나, 서식 차이까지 정리합니다. (예: "①" → "1")
NFKD NFD와 유사하나, 서식 차이까지 정리합니다.

03.01. NFC (합쳐진 형태)와 NFD (분해된 형태)의 차이 예시

// 단일 문자 (U+00E9)
const nfc = "é".normalize("NFC"); 
// 분해된 형태 (U+0065 U+0301)
const nfd = "é".normalize("NFD"); 

// false (유니코드 값이 다름)
console.log(nfc === nfd); 

04. 응용 사례

04.01. 문자열 비교 및 검색 개선

데이터베이스에 저장된 문자열과 사용자가 입력한 문자열이 유니코드 조합 방식에 따라 다르게 저장될 경우, 검색 전에 normalize()를 적용하면 동일한 문자열로 인식할 수 있습니다.

예시: 사용자 입력과 DB 저장값 정규화

// 사용자가 입력한 값
const searchKeyword = "éclair".normalize("NFC"); 
// DB에 저장된 값 (분해된 형태)
const databaseEntry = "éclair".normalize("NFC"); 

// true (정규화 후 일치)
console.log(searchKeyword === databaseEntry); 

주의: normalize()를 적용하지 않으면 "éclair" !== "éclair"와 같이 검색이 실패할 수 있습니다.


04.02. 파일 시스템에서 파일 이름 정규화

운영체제마다 유니코드 저장 방식이 다를 수 있습니다. 예를 들어:

  • macOS는 파일 이름을 NFD(분해된 형태)로 저장합니다.
  • Windows는 NFC(합쳐진 형태)로 저장합니다.

예시: macOS와 Windows 간 파일명 통일

const filenameMac = "café".normalize("NFD");
const filenameWindows = "café".normalize("NFC");

// false (운영체제 간 다를 수 있음)
console.log(filenameMac === filenameWindows); 

// 모든 파일명을 NFC로 변환하여 저장 시 호환성 문제 해결 가능
const normalizedFilename = filenameMac.normalize("NFC");
console.log(normalizedFilename === filenameWindows); // true

04.03. 다국어 처리 (한국어, 일본어, 중국어 포함)

특정 문자는 비슷해 보이나 유니코드 값이 다를 수 있습니다.

예를 들어, 全角 (전각) 문자半角 (반각) 문자의 경우:

  • 全角 문자: "ABC123" (전각)
  • 半角 문자: "ABC123" (반각)

예시: 전각 문자와 반각 문자 정규화

// 전각
const fullWidth = "ABC123"; 
// 반각
const halfWidth = "ABC123"; 

// true (NFKC 정규화 적용 시 전각 → 반각 변환)
console.log(fullWidth.normalize("NFKC") === halfWidth); 

참고: NFKC 정규화를 사용하면 전각 문자를 반각 문자로 변환할 수 있습니다.


04.04. 한글 자모 조합 (한글 입력기)

한글의 경우, 초성, 중성, 종성이 조합되어 완성형 문자가 됩니다.

normalize()를 사용하면 유니코드 조합형인 경우에는 조합이 가능하지만, 개별 한글 자모는 조합하지 않습니다.

예시: 한글 조합 가능 여부 확인

// 초성 "ᄀ"과 중성 "ᅡ"가 분해된 형태
const decomposedHangul = "가"; 
const composedHangul = decomposedHangul.normalize("NFC");

// "가"
console.log(composedHangul); 
// true (완성형 한글로 변환됨)
console.log(composedHangul === "가"); 

그러나 "ㄱㅏ".normalize("NFC")의 경우, 분해된 한글 자모는 그대로 유지됩니다.

이는 normalize()유니코드 조합형에 대해서만 동작하며, 개별 한글 자모 조합은 지원하지 않기 때문입니다.


05. normalize() 사용 시 주의할 점

  1. 모든 문자열이 변환되는 것은 아닙니다.
    • 예를 들어, "ㄱㅏ".normalize("NFC")"가"로 변환되지 않습니다.
    • normalize()유니코드 조합형에 대해서만 변환을 수행합니다.
  2. 언어별 변환 결과 차이
    • 일본어의 半角カナ (반각 가타카나)NFKC를 적용하면 全角カナ (전각 가타카나)로 변환됩니다.
  3. 서식 차이 정리 시 주의
    • NFKC 또는 NFKD를 사용할 경우, 서식 차이까지 제거됩니다.
    • 예를 들어, "①".normalize("NFKC")"1"로, "Ⅷ".normalize("NFKC")"8"로 변환됩니다.

06. 정리

기능 설명
normalize("NFC") 조합 가능한 문자를 하나의 문자로 변환합니다. (기본값)
normalize("NFD") 문자를 가능한 한 분해합니다.
normalize("NFKC") NFC 정규화에 서식 차이 정리까지 추가하여 변환합니다. (예: ① → 1)
normalize("NFKD") NFD 정규화에 서식 차이 정리까지 추가하여 변환합니다.

07. 언제 사용하면 좋은가?

07.01. 문자열 비교

같은 의미의 문자열이 유니코드 조합 방식에 따라 다르게 표현되는 경우 사용할 수 있습니다.

유니코드 조합 방식에 따라 다르게 표현된 문자열을 정규화하여 비교하는 예시입니다.

// 예시: "éclair"가 두 가지 방식으로 표현된 경우

// 단일 문자 형식
const str1 = "éclair".normalize("NFC");       
// 분해된 문자 형식
const str2 = "e\u0301clair".normalize("NFC");   

// true
console.log(str1 === str2); 

07.02. 검색 기능 개선

유니코드 차이로 인한 검색 실패를 방지하기 위해 사용할 수 있습니다.

검색 시, 데이터베이스에 저장된 문자열과 사용자의 입력값을 동일한 정규화 방식으로 변환하여 일치 여부를 확인하는 예시입니다.

// 예시: 사용자 입력과 DB 저장값 정규화
const userInput = "café".normalize("NFC");
const dbEntry = "cafe\u0301".normalize("NFC");

if (userInput === dbEntry) {
  console.log("검색 성공: 문자열이 일치합니다.");
} else {
  console.log("검색 실패: 문자열이 일치하지 않습니다.");
}

07.03. 파일 시스템 호환성 유지

macOS와 Windows 간 파일명 저장 방식 차이로 인한 문제 해결에 사용할 수 있습니다.

macOS와 Windows 간 파일명 저장 방식의 차이를 해결하기 위해, 모든 파일명을 NFC 형식으로 통일하는 예시입니다.

// 예시: macOS에서 가져온 파일명 (NFD)과 Windows의 파일명 (NFC)
const filenameMac = "café".normalize("NFD");
const filenameWindows = "café".normalize("NFC");

console.log(filenameMac === filenameWindows); // false

// 모든 파일명을 NFC로 변환하여 저장하면 호환성 유지 가능
const normalizedFilename = filenameMac.normalize("NFC");
console.log(normalizedFilename === filenameWindows); // true

07.04. 다국어 처리

일본어, 중국어 등 다양한 언어에서 발생하는 유니코드 표현 차이를 통일하기 위해 사용할 수 있습니다.

일본어 등 다국어의 전각(全角) 문자와 반각(半角) 문자를 정규화하는 예시입니다.

// 예시: 전각 문자와 반각 문자를 NFKC 정규화를 통해 비교

// 전각 문자
const fullWidth = "ABC123";  
// 반각 문자
const halfWidth = "ABC123";        

// true
console.log(fullWidth.normalize("NFKC") === halfWidth); 

08. 추가 고려 사항

  • 성능 문제
    • 정규화를 과도하게 사용하면 성능에 영향을 줄 수 있으므로, 필요한 경우에만 적용하는 것이 좋습니다.
  • 데이터 저장
    • 입력 데이터를 저장하기 전에 정규화를 적용하면, 이후 검색 및 비교 시 일관성을 유지할 수 있습니다.
  • 테스트 케이스
    • 다양한 언어와 문자를 포함하는 테스트 케이스를 마련하여 정규화 적용 결과를 검증하는 것이 중요합니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
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 28 29 30
글 보관함