티스토리 뷰
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() 사용 시 주의할 점
- 모든 문자열이 변환되는 것은 아닙니다.
- 예를 들어,
"ㄱㅏ".normalize("NFC")는"가"로 변환되지 않습니다. normalize()는 유니코드 조합형에 대해서만 변환을 수행합니다.
- 예를 들어,
- 언어별 변환 결과 차이
- 일본어의 半角カナ (반각 가타카나)도
NFKC를 적용하면 全角カナ (전각 가타카나)로 변환됩니다.
- 일본어의 半角カナ (반각 가타카나)도
- 서식 차이 정리 시 주의
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. 추가 고려 사항
- 성능 문제
- 정규화를 과도하게 사용하면 성능에 영향을 줄 수 있으므로, 필요한 경우에만 적용하는 것이 좋습니다.
- 데이터 저장
- 입력 데이터를 저장하기 전에 정규화를 적용하면, 이후 검색 및 비교 시 일관성을 유지할 수 있습니다.
- 테스트 케이스
- 다양한 언어와 문자를 포함하는 테스트 케이스를 마련하여 정규화 적용 결과를 검증하는 것이 중요합니다.
'FrontEnd > javascript' 카테고리의 다른 글
| Bitwise Operation (0) | 2025.03.21 |
|---|---|
| [JavaScript] CORS(Cross-Origin Resource Sharing) (0) | 2025.03.21 |
| [XSS] HTML 엔티티 디코딩 시 XSS 공격 방지를 위한 안전한 처리 방법 (0) | 2025.03.19 |
| [JavaScript] 자바스크립트 원시 래퍼 객체 (0) | 2025.03.18 |
| [JavaScript] 자바스크립트 날짜 처리, 타임존 DST, 데이터 표현 방식 (0) | 2025.03.18 |
- Total
- Today
- Yesterday
- primitive
- deep dive
- double-linked-list
- react-router
- scoped slot
- interning
- ViTE
- npm ci
- string table
- nuxt
- bundler
- pnpm 명령어
- react
- prototype
- JavaScript
- 바이트 코드
- string
- library mode
- object literal
- pakage-lock.json
- vue
- vee-validate
- JIT
- useasyncdata
- webpack
- premitive
- TypeScript
- refrerence
- uselazyasyncdata
- 모노레포 스크립트
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
