Start · Sprachen · JavaScript · Referenz · String.prototype.normalize()

String.prototype.normalize()

Methode

Gibt die Unicode-Normalisierungsform eines Strings zurück (<code>NFC</code>, <code>NFD</code>, <code>NFKC</code> oder <code>NFKD</code>).

seit JavaScript ES2015 Kategorie: method-property

Signatur

String.prototype.normalize(form)

Beschreibung

Unicode erlaubt es, viele Zeichen auf mehr als eine Weise darzustellen. So kann "é" entweder als einzelner Codepunkt U+00E9 (vorkomponiert) oder als "e" plus kombinierender Akut U+0301 (zerlegt) kodiert sein. Beide Varianten sehen gleich aus, sind aber für ===, includes() oder als Map-Schlüssel verschieden. normalize() bringt Strings in eine einheitliche Form, damit solche Vergleiche zuverlässig funktionieren.

Es gibt vier Normalisierungsformen:

  • NFC (Standard): kanonische Zerlegung, danach kanonische Zusammensetzung. Ergibt meist die kürzeste, „übliche“ Darstellung.
  • NFD: nur kanonische Zerlegung. Praktisch, um diakritische Zeichen abzutrennen und zu entfernen.
  • NFKC: Kompatibilitätszerlegung, danach kanonische Zusammensetzung. Wandelt z. B. Ligaturen ("fi" → "fi") oder hochgestellte Ziffern ("²" → "2") um.
  • NFKD: nur Kompatibilitätszerlegung.

Man verwendet normalize() typischerweise vor dem Vergleichen, Suchen, Deduplizieren oder Speichern von Benutzereingaben, Dateinamen (macOS speichert Dateinamen oft in NFD) oder Daten aus verschiedenen Quellen. Die Methode verändert den ursprünglichen String nicht, sondern liefert einen neuen.

Parameter

Name Typ Default Beschreibung
$form "NFC" | "NFD" | "NFKC" | "NFKD" "NFC" Die gewünschte Unicode-Normalisierungsform. Wird der Parameter weggelassen oder ist er undefined, wird "NFC" verwendet.

Rückgabewert

Typ
string
Beschreibung
Ein neuer String in der angegebenen Unicode-Normalisierungsform.

Beispiele

Gleich aussehende Strings zuverlässig vergleichen

const vorkomponiert = "Caf\u00E9";      // é als ein Codepunkt
const zerlegt = "Cafe\u0301";           // e + kombinierender Akut

console.log(vorkomponiert === zerlegt);
console.log(vorkomponiert.length, zerlegt.length);
console.log(vorkomponiert.normalize() === zerlegt.normalize());
false 4 5 true

Diakritische Zeichen entfernen (z. B. für Slugs oder Suche)

const entferneAkzente = (text) =>
  text.normalize("NFD").replace(/\p{Diacritic}/gu, "");

console.log(entferneAkzente("Crème brûlée à São Paulo"));

const slug = entferneAkzente("Élan & Café")
  .toLowerCase()
  .replace(/[^a-z0-9]+/g, "-")
  .replace(/^-|-$/g, "");
console.log(slug);
Creme brulee a Sao Paulo elan-cafe

Kompatibilitätsnormalisierung mit NFKC

const eingabe = "final x² ①";

console.log(eingabe.normalize("NFC"));
console.log(eingabe.normalize("NFKC"));
final x² ① final x2 1

Benutzernamen vor dem Speichern vereinheitlichen

const benutzer = new Set();

const registriere = (name) => {
  const schluessel = name.normalize("NFC").toLowerCase();
  if (benutzer.has(schluessel)) {
    return `"${name}" ist bereits vergeben`;
  }
  benutzer.add(schluessel);
  return `"${name}" registriert`;
};

console.log(registriere("Jos\u00E9"));
console.log(registriere("Jose\u0301"));
"José" registriert "José" ist bereits vergeben

// Wichtig · Fallstricke

  • Ein ungültiger Wert für form (z. B. "nfc" in Kleinbuchstaben) löst einen RangeError aus.
  • NFKC/NFKD sind verlustbehaftet: Aus "x²" wird "x2", aus "①" wird "1". Nur für Such- oder Vergleichsschlüssel verwenden, nicht, um Originaltexte zu überschreiben.
  • Normalisierung macht Vergleiche nicht unabhängig von Groß-/Kleinschreibung. Für sprachabhängige Vergleiche besser Intl.Collator oder localeCompare() mit sensitivity verwenden.
  • Sicherheit: Unterschiedliche Normalisierung kann zu Umgehungen führen, etwa bei Benutzernamen, Dateipfaden oder Filtern. Normalisiere Eingaben vor Validierung und Speicherung konsistent. Gegen Homoglyphen (z. B. kyrillisches "а" statt lateinischem "a") hilft normalize() nicht.
  • Die Methode ist bei langen Texten nicht kostenlos – bei vielen Vergleichen lieber einmal normalisieren und das Ergebnis zwischenspeichern.
  • string.length kann sich durch die Normalisierung ändern.
  • Kompatibilität: Seit ES2015 in allen modernen Browsern und in Node.js verfügbar (Baseline).