String.prototype.normalize()
Метод normalize()
(нормалізувати, привести до норми) значень повертає нормалізовану форму Unicode свого рядка.
Спробуйте його в дії
Синтаксис
normalize()
normalize(form)
Параметри
form
Необов'язковеФорма нормалізації Unicode, задана одним із чотирьох значень:
"NFC"
,"NFD"
,"NFKC"
чи"NFKD"
. Якщо цей параметр не задано, або переданоundefined
, буде використана"NFC"
.Ці варіанти мають наступні значення:
"NFC"
Канонічна декомпозиція з наступною Канонічною композицією.
"NFD"
Канонічна декомпозиція.
"NFKC"
Сумісна декомпозиція з наступною Канонічною композицією.
"NFKD"
Сумісна декомпозиція.
Повернене значення
Рядок, що містить нормалізовану форму Unicode переданого рядка.
Винятки
RangeError
Викидається, якщо аргумент
form
містить значення, відмінне від вказаних вище.
Опис
Кожному окремому символу Unicode призначає числове значення, назване кодовою точкою. Наприклад, для літери "A"
визначено кодову точку U+0041. Утім, інколи один і той самий абстрактний символ можна позначати декількома різними кодовими точками, або навіть їх послідовністю. Наприклад, символ "ñ"
можна позначити одним із двох способів:
- Єдина кодова точка U+00F1.
- Кодова точка літери
"n"
(U+006E), із кодовою точкою комбінованої тильди (U+0303) одразу за нею.
const string1 = "\u00F1";
const string2 = "\u006E\u0303";
console.log(string1); // ñ
console.log(string2); // ñ
Щоправда, оскільки це різні кодові точки, під час порівняння такі рядки не будуть вважатися однаковими. Більш того, кількість кодових точок теж відрізняється, тому довжини цих рядків також різні.
const string1 = "\u00F1"; // ñ
const string2 = "\u006E\u0303"; // ñ
console.log(string1 === string2); // false
console.log(string1.length); // 1
console.log(string2.length); // 2
Метод normalize()
допомагає розв'язати цю проблему шляхом перетворення рядка на нормалізовану форму, спільну для всіх послідовностей кодових точок, яким відповідають однакові символи. Існує дві основні форми нормалізації: одна заснована на канонічній еквівалентності, а інша — на сумісності.
Нормалізація через канонічну еквівалентність
В Unicode дві послідовності кодових точок канонічно еквівалентні, якщо вони позначають ті самі абстрактні символи. Вони повинні завжди мати однаковий візуальний вигляд і поведінку (наприклад, вони повинні завжди однаково сортуватись).
Для отримання форми рядка, яка буде однаковою для всіх канонічно еквівалентних рядків, метод normalize()
вживається з аргументом "NFD"
чи "NFC"
. У наведеному нижче прикладі відбувається нормалізація двох різних варіацій символу "ñ"
:
let string1 = "\u00F1"; // ñ
let string2 = "\u006E\u0303"; // ñ
string1 = string1.normalize("NFD");
string2 = string2.normalize("NFD");
console.log(string1 === string2); // true
console.log(string1.length); // 2
console.log(string2.length); // 2
Компонована те декомпонована форми
Варто зауважити, що довжина форми, нормалізованої методом "NFD"
, дорівнює 2
. Так виходить, тому що "NFD"
видає декомпоновану версію канонічної форми, в якій поодинокі кодові точки розділені на декілька базових. Декомпонована канонічна форма літери "ñ"
— це послідовність "\u006E\u0303"
.
Для отримання компонованої канонічної форми, в якій декілька послідовних кодових точок заміняються їх одинарними відповідниками (де це можливо), слід передати аргумент "NFC"
. Компонована канонічна форма літери "ñ"
— це "\u00F1"
:
let string1 = "\u00F1"; // ñ
let string2 = "\u006E\u0303"; // ñ
string1 = string1.normalize("NFC");
string2 = string2.normalize("NFC");
console.log(string1 === string2); // true
console.log(string1.length); // 1
console.log(string2.length); // 1
console.log(string2.codePointAt(0).toString(16)); // f1
Сумісна нормалізація
В Unicode дві послідовності кодових точок — сумісні, якщо вони позначають однакові абстрактні символи. Сумісні форми повинні однаково оброблятись у деяких (проте не обов'язково у всіх) застосунках.
Всі канонічно еквівалентні форми також є сумісними, але не навпаки.
Наприклад:
- кодова точка U+FB00 позначає лігатуру
"ff"
. Вона сумісна з двома послідовними кодовими точками U+0066 ("ff"
). - кодова точка U+24B9 позначає символ
"Ⓓ"
. Вона сумісна з кодовою точкою U+0044 ("D"
).
В одних контекстах (зокрема сортування) їх слід вважати еквівалентними, в інших (таких, як зовнішній вигляд) — ні, тому вони не є канонічно еквівалентними.
Для отримання форми рядка, яка буде однаковою для всіх сумісних рядків, використовується normalize()
з аргументом "NFKD"
чи "NFKC"
:
let string1 = "\uFB00";
let string2 = "\u0066\u0066";
console.log(string1); // ff
console.log(string2); // ff
console.log(string1 === string2); // false
console.log(string1.length); // 1
console.log(string2.length); // 2
string1 = string1.normalize("NFKD");
string2 = string2.normalize("NFKD");
console.log(string1); // ff <- вигляд змінився
console.log(string2); // ff
console.log(string1 === string2); // true
console.log(string1.length); // 2
console.log(string2.length); // 2
Під час застосування сумісної нормалізації важливо врахувати, для чого ті рядки будуть потім використовуватись, оскільки така нормалізована форма підходить не для всіх застосувань. В наведеному вище прикладі нормалізація чудово підходить для пошуку, оскільки вона дає змогу користувачу знайти рядок шляхом пошуку літери "f"
. Проте вона може не підходити для зображення, оскільки візуально вигляд нормалізованої форми відрізняється.
Як і з канонічною нормалізацією, можна отримати компоновану чи декомпоновану сумісні форми шляхом передачі аргументів "NFKD"
чи "NFKC"
, відповідно.
Приклади
Застосування normalize()
// Початковий рядок
// U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
// U+0323: COMBINING DOT BELOW
const str = "\u1E9B\u0323";
// Канонічна компонована форма (NFC)
// U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
// U+0323: COMBINING DOT BELOW
str.normalize("NFC"); // '\u1E9B\u0323'
str.normalize(); // те саме, що й вище
// Канонічна декомпонована форма (NFD)
// U+017F: LATIN SMALL LETTER LONG S
// U+0323: COMBINING DOT BELOW
// U+0307: COMBINING DOT ABOVE
str.normalize("NFD"); // '\u017F\u0323\u0307'
// Сумісна компонована форма (NFKC)
// U+1E69: LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
str.normalize("NFKC"); // '\u1E69'
// Сумісна декомпонована форма (NFKD)
// U+0073: LATIN SMALL LETTER S
// U+0323: COMBINING DOT BELOW
// U+0307: COMBINING DOT ABOVE
str.normalize("NFKD"); // '\u0073\u0323\u0307'
Специфікації
Сумісність із браузерами
desktop | mobile | server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
normalize
|
Chrome Full support 34 | Edge Full support 12 | Firefox Full support 31 | Internet Explorer No support Ні | Opera Full support 21 | Safari Full support 10 | WebView Android No support Ні | Chrome Android Full support 34 | Firefox for Android Full support 31 | Opera Android Full support 21 | Safari on iOS Full support 10 | Samsung Internet Full support 2.0 | Deno Full support 1.0 | Node.js Full support 0.12.0 |