๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์•Œ์•„๋‘๋ฉด ์ข‹์€ ๊ฐœ๋ฐœ์ง€์‹/Web

Web์—์„œ ๋ฌธ์ž์—ด NFD -> NFC ๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ

by ๋น„์ „@๊ณต์ž 2024. 12. 25.

 

์ธํ„ฐ๋„ท Web๋ธŒ๋ผ์šฐ์ €๋กœ ๋ณต์‚ฌํ•˜๊ธฐ๋ฅผ ํ–ˆ๋Š”๋ฐ ํ•œ๊ธ€์ด ๋Š˜์–ด์ ธ ๋ณด์ด๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

 

 

๊ฐ€๋ น ๊ฐ™์€ ์• ๊ตญ๊ฐ€๋ฅผ ํƒ€์ดํ•‘ํ–ˆ์–ด๋„ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋Š” ๋‹ค๋ฅด๋‹ค.

 

"NFC (์œˆ๋„์šฐ ๊ธฐ๋ณธ)" ์œผ๋กœ ์ž‘์„ฑ

๋™ํ•ด๋ฌผ๊ณผ ๋ฐฑ๋‘์‚ฐ์ด ๋งˆ๋ฅด๊ณ  ๋‹ณ๋„๋ก
ํ•˜๋А๋‹˜์ด ๋ณด์šฐํ•˜์‚ฌ ์šฐ๋ฆฌ๋‚˜๋ผ ๋งŒ์„ธ

"NFD (MacOS ๊ธฐ๋ณธ)" ์œผ๋กœ ์ž‘์„ฑ

แ„ƒแ…ฉแ†ผแ„’แ…ขแ„†แ…ฎแ†ฏแ„€แ…ช แ„‡แ…ขแ†จแ„ƒแ…ฎแ„‰แ…กแ†ซแ„‹แ…ต แ„†แ…กแ„…แ…ณแ„€แ…ฉ แ„ƒแ…กแ†ถแ„ƒแ…ฉแ„…แ…ฉแ†จ

แ„’แ…กแ„‚แ…ณแ„‚แ…ตแ†ทแ„‹แ…ต แ„‡แ…ฉแ„‹แ…ฎแ„’แ…กแ„‰แ…ก แ„‹แ…ฎแ„…แ…ตแ„‚แ…กแ„…แ…ก แ„†แ…กแ†ซแ„‰แ…ฆ

 

Chrome๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•œ๊ธ€์„ ํ‘œ๊ธฐํ•  ๋•Œ, NFD ๋ฌธ์ž์—ด์„ ์ž๋™์œผ๋กœ NFC ๋กœ ์น˜ํ™˜ํ•ด์ฃผ์ง€๋งŒ

์ด๊ฒƒ์„ ์›น์ƒ์—์„œ Ctrl + C๋ฅผ ๋ˆŒ๋Ÿฌ์„œ ๋ณต์‚ฌํ•˜๊ฒŒ ๋˜๋ฉด ๋‹ค๋ฅธ๊ฐ’์œผ๋กœ ๋ณด์ด๊ฒŒ ๋œ๋‹ค.

 

ํด๋ฆฝ๋ณด๋“œ์—์„œ ๋ณด์ด๋Š” ๊ฐ’

 

๋ฉ”๋ชจ์žฅ์—์„œ ๋ณด์ด๋Š” ๊ฐ’

 

์ด ๊ฐ’์„ NFD-> NFC ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”๋ฐ Javascript ์—์„œ ํ• ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ ์–ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

String.prototype.normalize()

 

๋กœ ์น˜ํ™˜ ๊ฐ€๋Šฅํ•˜๋‹ค.

Mdn Web Docs ์˜ˆ์ œ

// ๊ฒฐํ•ฉ๋œ ํ•œ๊ธ€ ๋ฌธ์ž์—ด

// U+D55C: ํ•œ(HANGUL SYLLABLE HAN)
// U+AE00: ๊ธ€(HANGUL SYLLABLE GEUL)
var first = "\uD55C\uAE00";

// ์ •๊ทœํ˜• ์ •์ค€ ๋ถ„ํ•ด (NFD)
// ์ •์ค€ ๋ถ„ํ•ด ๊ฒฐ๊ณผ ์ดˆ์„ฑ, ์ค‘์„ฑ, ์ข…์„ฑ์˜ ์ž์†Œ๋ถ„๋ฆฌ๊ฐ€ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.
// ์ผ๋ถ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ๊ฒฐ๊ณผ๊ฐ’ 'แ„’แ…กแ†ซแ„€แ…ณแ†ฏ'์ด ์ž์†Œ๋ถ„๋ฆฌ๋œ ์ƒํƒœ๋กœ ๋ณด์—ฌ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// U+1112: แ„’(HANGUL CHOSEONG HIEUH)
// U+1161: แ…ก(HANGUL JUNGSEONG A)
// U+11AB: แ†ซ(HANGUL JONGSEONG NIEUN)
// U+1100: แ„€(HANGUL CHOSEONG KIYEOK)
// U+1173: แ…ณ(HANGUL JUNGSEONG EU)
// U+11AF: แ†ฏ(HANGUL JONGSEONG RIEUL)
var second = first.normalize("NFD"); // '\u1112\u1161\u11AB\u1100\u1173\u11AF'

// ์ •๊ทœํ˜• ์ •์ค€ ๊ฒฐํ•ฉ (NFC)
// ์ •์ค€ ๊ฒฐํ•ฉ ๊ฒฐ๊ณผ ์ž์†Œ๋ถ„๋ฆฌ ๋˜์—ˆ๋˜ ํ•œ๊ธ€์ด ๊ฒฐํ•ฉ๋ฉ๋‹ˆ๋‹ค.

// U+D55C: ํ•œ(HANGUL SYLLABLE HAN)
// U+AE00: ๊ธ€(HANGUL SYLLABLE GEUL)
var third = second.normalize("NFC"); // '\uD55C\uAE00'

console.log(second === third); // ๊ฐ™์€ ๊ธ€์ž์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ false๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

 

 

์›น์ƒ์—์„œ๋Š” ์ด๋Ÿฐ์‹์œผ๋กœ ์น˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

// ๋ชจ๋“  "tile-text" ํด๋ž˜์Šค๋ฅผ ๊ฐ€์ง„ <p> ์š”์†Œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
const elements = document.querySelectorAll('.tile-text');

// ๊ฐ ์š”์†Œ์˜ ํ…์ŠคํŠธ ๋‚ด์šฉ์„ NFC๋กœ normalizeํ•ฉ๋‹ˆ๋‹ค.
elements.forEach(element => {
    // ํ˜„์žฌ ์š”์†Œ์˜ ํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    const originalText = element.textContent;

    // NFC ๋ฐฉ์‹์œผ๋กœ normalizeํ•œ ํ›„ ๋‹ค์‹œ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    element.textContent = originalText.normalize('NFC');
});

๋Œ“๊ธ€