String.prototype.normalize()
Метод normalize()
повертає нормалізовану форму Unicode рядка.
Спробуйте його в дії
Синтаксис
normalize()
normalize(form)
Параметри
form
Необов'язковеФорма нормалізації Unicode, задана одним із чотирьох значень:
"NFC"
,"NFD"
,"NFKC"
чи"NFKD"
. Якщо цей параметр не задано, або переданоundefined
, буде використана"NFC"
.Ці варіанти мають наступні значення:
"NFC"
Канонічна декомпозиція з наступною Канонічною композицією.
"NFD"
Канонічна декомпозиція.
"NFKC"
Сумісна декомпозиція з наступною Канонічною композицією.
"NFKD"
Сумісна декомпозиція.
Повернене значення
Рядок, що містить нормалізовану форму Unicode переданого рядка.
Викинуті помилки
RangeError
Викидається помилка
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 No | Opera Full support 21 | Safari Full support 10 | WebView Android No support No | 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 |