Wie man Locale-Identifikatoren in Standardform normalisiert
Konvertieren Sie Locale-Identifikatoren in kanonisches Format mit korrekter Groß-/Kleinschreibung und Komponentenreihenfolge
Einführung
Locale-Identifikatoren können auf viele verschiedene Arten geschrieben werden, während sie sich auf dieselbe Sprache und Region beziehen. Ein Benutzer könnte EN-us, en-US oder en-us schreiben, und alle drei repräsentieren amerikanisches Englisch. Beim Speichern, Vergleichen oder Anzeigen von Locale-Identifikatoren führen diese Variationen zu Inkonsistenzen.
Die Normalisierung konvertiert Locale-Identifikatoren in eine standardisierte kanonische Form. Dieser Prozess passt die Groß-/Kleinschreibung von Komponenten an, ordnet Erweiterungsschlüsselwörter alphabetisch und erzeugt eine konsistente Darstellung, auf die Sie sich in Ihrer gesamten Anwendung verlassen können.
JavaScript bietet integrierte Methoden zur automatischen Normalisierung von Locale-Identifikatoren. Dieser Leitfaden erklärt, was Normalisierung bedeutet, wie Sie sie in Ihrem Code anwenden und wann normalisierte Identifikatoren Ihre Internationalisierungslogik verbessern.
Was Normalisierung für Locale-Identifikatoren bedeutet
Die Normalisierung transformiert einen Locale-Identifikator in seine kanonische Form gemäß dem BCP-47-Standard und den Unicode-Spezifikationen. Die kanonische Form hat spezifische Regeln für Groß-/Kleinschreibung, Reihenfolge und Struktur.
Ein normalisierter Locale-Identifikator folgt diesen Konventionen:
- Sprachcodes sind kleingeschrieben
- Schriftcodes sind im Titelformat mit großgeschriebenem ersten Buchstaben
- Regionscodes sind großgeschrieben
- Variantencodes sind kleingeschrieben
- Erweiterungsschlüsselwörter sind alphabetisch sortiert
- Erweiterungsattribute sind alphabetisch sortiert
Diese Regeln schaffen eine einzige Standarddarstellung für jede Locale. Unabhängig davon, wie ein Benutzer einen Locale-Identifikator schreibt, ist die normalisierte Form immer dieselbe.
Die Normalisierungsregeln verstehen
Jede Komponente eines Locale-Identifikators hat in der kanonischen Form eine spezifische Konvention für die Groß-/Kleinschreibung.
Groß- und Kleinschreibung von Sprachen
Sprachcodes verwenden immer Kleinbuchstaben:
en (correct)
EN (incorrect, but normalizes to en)
eN (incorrect, but normalizes to en)
Dies gilt sowohl für zwei- als auch für dreistellige Sprachcodes.
Groß- und Kleinschreibung von Schriften
Schriftcodes verwenden Title Case, wobei der erste Buchstabe großgeschrieben und die verbleibenden drei Buchstaben kleingeschrieben werden:
Hans (correct)
hans (incorrect, but normalizes to Hans)
HANS (incorrect, but normalizes to Hans)
Gängige Schriftcodes sind Latn für Lateinisch, Cyrl für Kyrillisch, Hans für vereinfachte Han-Zeichen und Hant für traditionelle Han-Zeichen.
Groß- und Kleinschreibung von Regionen
Regionscodes verwenden immer Großbuchstaben:
US (correct)
us (incorrect, but normalizes to US)
Us (incorrect, but normalizes to US)
Dies gilt für die zweistelligen Ländercodes, die in den meisten Locale-Identifikatoren verwendet werden.
Reihenfolge von Erweiterungen
Unicode-Erweiterungs-Tags enthalten Schlüsselwörter, die Formatierungspräferenzen spezifizieren. In der kanonischen Form erscheinen diese Schlüsselwörter in alphabetischer Reihenfolge nach ihrem Schlüssel:
en-US-u-ca-gregory-nu-latn (correct)
en-US-u-nu-latn-ca-gregory (incorrect, but normalizes to first form)
Der Kalenderschlüssel ca kommt alphabetisch vor dem Zahlensystemschlüssel nu, daher erscheint ca-gregory zuerst in der normalisierten Form.
Verwendung von Intl.getCanonicalLocales zur Normalisierung
Die Methode Intl.getCanonicalLocales() normalisiert Locale-Identifikatoren und gibt sie in kanonischer Form zurück. Dies ist die primäre Methode zur Normalisierung in JavaScript.
const normalized = Intl.getCanonicalLocales("EN-us");
console.log(normalized);
// ["en-US"]
Die Methode akzeptiert einen Locale-Identifikator mit beliebiger Groß- und Kleinschreibung und gibt die korrekt geschriebene kanonische Form zurück.
Normalisierung von Sprachcodes
Die Methode konvertiert Sprachcodes in Kleinbuchstaben:
const result = Intl.getCanonicalLocales("FR-fr");
console.log(result);
// ["fr-FR"]
Der Sprachcode FR wird in der Ausgabe zu fr.
Normalisierung von Schriftcodes
Die Methode konvertiert Skriptcodes in Titelschreibweise:
const result = Intl.getCanonicalLocales("zh-HANS-cn");
console.log(result);
// ["zh-Hans-CN"]
Der Skriptcode HANS wird zu Hans, und der Regionscode cn wird zu CN.
Normalisierung von Regionscodes
Die Methode konvertiert Regionscodes in Großbuchstaben:
const result = Intl.getCanonicalLocales("en-gb");
console.log(result);
// ["en-GB"]
Der Regionscode gb wird in der Ausgabe zu GB.
Normalisierung von Erweiterungsschlüsselwörtern
Die Methode sortiert Erweiterungsschlüsselwörter alphabetisch:
const result = Intl.getCanonicalLocales("en-US-u-nu-latn-hc-h12-ca-gregory");
console.log(result);
// ["en-US-u-ca-gregory-hc-h12-nu-latn"]
Die Schlüsselwörter werden von nu-latn-hc-h12-ca-gregory zu ca-gregory-hc-h12-nu-latn umsortiert, da ca alphabetisch vor hc und hc vor nu kommt.
Normalisierung mehrerer Locale-Identifikatoren
Die Methode Intl.getCanonicalLocales() akzeptiert ein Array von Locale-Identifikatoren und normalisiert alle:
const locales = ["EN-us", "fr-FR", "ZH-hans-cn"];
const normalized = Intl.getCanonicalLocales(locales);
console.log(normalized);
// ["en-US", "fr-FR", "zh-Hans-CN"]
Jede Locale im Array wird in ihre kanonische Form konvertiert.
Entfernung von Duplikaten
Die Methode entfernt doppelte Locale-Identifikatoren nach der Normalisierung. Wenn mehrere Eingabewerte zur gleichen kanonischen Form normalisiert werden, enthält das Ergebnis nur eine Kopie:
const locales = ["en-US", "EN-us", "en-us"];
const normalized = Intl.getCanonicalLocales(locales);
console.log(normalized);
// ["en-US"]
Alle drei Eingaben repräsentieren dieselbe Locale, daher enthält die Ausgabe einen einzigen normalisierten Identifikator.
Diese Deduplizierung ist nützlich bei der Verarbeitung von Benutzereingaben oder beim Zusammenführen von Locale-Listen aus mehreren Quellen.
Umgang mit ungültigen Identifikatoren
Wenn ein Locale-Identifikator im Array ungültig ist, wirft die Methode einen RangeError:
try {
Intl.getCanonicalLocales(["en-US", "invalid", "fr-FR"]);
} catch (error) {
console.error(error.message);
// "invalid is not a structurally valid language tag"
}
Beim Normalisieren von benutzerbereitgestellten Listen sollten Sie jeden Locale-Identifikator einzeln validieren oder Fehler abfangen, um zu identifizieren, welche spezifischen Identifikatoren ungültig sind.
Verwendung von Intl.Locale zur Normalisierung
Der Intl.Locale-Konstruktor normalisiert auch Locale-Identifikatoren beim Erstellen von Locale-Objekten. Sie können auf die normalisierte Form über die toString()-Methode zugreifen.
const locale = new Intl.Locale("EN-us");
console.log(locale.toString());
// "en-US"
Der Konstruktor akzeptiert jede gültige Groß-/Kleinschreibung und erzeugt ein normalisiertes Locale-Objekt.
Zugriff auf normalisierte Komponenten
Jede Eigenschaft des Locale-Objekts gibt die normalisierte Form dieser Komponente zurück:
const locale = new Intl.Locale("ZH-hans-CN");
console.log(locale.language);
// "zh"
console.log(locale.script);
// "Hans"
console.log(locale.region);
// "CN"
console.log(locale.baseName);
// "zh-Hans-CN"
Die Eigenschaften language, script und region verwenden alle die korrekte Groß-/Kleinschreibung für die kanonische Form.
Normalisierung mit Optionen
Wenn Sie ein Locale-Objekt mit Optionen erstellen, normalisiert der Konstruktor sowohl den Basis-Identifikator als auch die Optionen:
const locale = new Intl.Locale("EN-us", {
calendar: "gregory",
numberingSystem: "latn",
hourCycle: "h12"
});
console.log(locale.toString());
// "en-US-u-ca-gregory-hc-h12-nu-latn"
Die Extension-Keywords erscheinen in der Ausgabe in alphabetischer Reihenfolge, obwohl das Options-Objekt keine bestimmte Reihenfolge vorgibt.
Warum Normalisierung wichtig ist
Normalisierung sorgt für Konsistenz in Ihrer Anwendung. Wenn Sie Locale-Identifikatoren speichern, anzeigen oder vergleichen, verhindert die Verwendung der kanonischen Form subtile Bugs und verbessert die Zuverlässigkeit.
Konsistente Speicherung
Beim Speichern von Locale-Identifikatoren in Datenbanken, Konfigurationsdateien oder Local Storage verhindern normalisierte Formen Duplikate:
const userPreferences = new Set();
function saveUserLocale(identifier) {
const normalized = Intl.getCanonicalLocales(identifier)[0];
userPreferences.add(normalized);
}
saveUserLocale("en-US");
saveUserLocale("EN-us");
saveUserLocale("en-us");
console.log(userPreferences);
// Set { "en-US" }
Ohne Normalisierung würde das Set drei Einträge für dieselbe Locale enthalten. Mit Normalisierung enthält es korrekterweise einen.
Zuverlässiger Vergleich
Der Vergleich von Locale-Identifikatoren erfordert Normalisierung. Zwei Identifikatoren, die sich nur in der Groß-/Kleinschreibung unterscheiden, repräsentieren dieselbe Locale:
function isSameLocale(locale1, locale2) {
const normalized1 = Intl.getCanonicalLocales(locale1)[0];
const normalized2 = Intl.getCanonicalLocales(locale2)[0];
return normalized1 === normalized2;
}
console.log(isSameLocale("en-US", "EN-us"));
// true
console.log(isSameLocale("en-US", "en-GB"));
// false
Direkter String-Vergleich von nicht normalisierten Identifikatoren liefert falsche Ergebnisse.
Konsistente Anzeige
Beim Anzeigen von Locale-Identifikatoren für Benutzer oder in Debug-Ausgaben bieten normalisierte Formen eine konsistente Formatierung:
function displayLocale(identifier) {
try {
const normalized = Intl.getCanonicalLocales(identifier)[0];
return `Current locale: ${normalized}`;
} catch (error) {
return "Invalid locale identifier";
}
}
console.log(displayLocale("EN-us"));
// "Current locale: en-US"
console.log(displayLocale("zh-HANS-cn"));
// "Current locale: zh-Hans-CN"
Benutzer sehen korrekt formatierte Locale-Identifikatoren unabhängig vom Eingabeformat.
Praktische Anwendungen
Die Normalisierung löst typische Probleme beim Arbeiten mit Locale-Bezeichnern in realen Anwendungen.
Normalisierung von Benutzereingaben
Wenn Benutzer Locale-Bezeichner in Formularen oder Einstellungen eingeben, normalisieren Sie die Eingabe, bevor Sie sie speichern:
function processLocaleInput(input) {
try {
const normalized = Intl.getCanonicalLocales(input)[0];
return {
success: true,
locale: normalized
};
} catch (error) {
return {
success: false,
error: "Please enter a valid locale identifier"
};
}
}
const result = processLocaleInput("fr-ca");
console.log(result);
// { success: true, locale: "fr-CA" }
Dies stellt ein konsistentes Format in Ihrer Datenbank oder Konfiguration sicher.
Aufbau von Locale-Lookup-Tabellen
Wenn Sie Lookup-Tabellen für Übersetzungen oder locale-spezifische Daten erstellen, verwenden Sie normalisierte Schlüssel:
const translations = new Map();
function addTranslation(locale, key, value) {
const normalized = Intl.getCanonicalLocales(locale)[0];
if (!translations.has(normalized)) {
translations.set(normalized, {});
}
translations.get(normalized)[key] = value;
}
addTranslation("en-us", "hello", "Hello");
addTranslation("EN-US", "goodbye", "Goodbye");
console.log(translations.get("en-US"));
// { hello: "Hello", goodbye: "Goodbye" }
Beide Aufrufe von addTranslation verwenden denselben normalisierten Schlüssel, sodass die Übersetzungen im selben Objekt gespeichert werden.
Zusammenführen von Locale-Listen
Wenn Sie Locale-Bezeichner aus mehreren Quellen kombinieren, normalisieren und deduplizieren Sie diese:
function mergeLocales(...sources) {
const allLocales = sources.flat();
const normalized = Intl.getCanonicalLocales(allLocales);
return normalized;
}
const userLocales = ["en-us", "fr-FR"];
const appLocales = ["EN-US", "de-de"];
const systemLocales = ["en-US", "es-mx"];
const merged = mergeLocales(userLocales, appLocales, systemLocales);
console.log(merged);
// ["en-US", "fr-FR", "de-DE", "es-MX"]
Die Methode entfernt Duplikate und normalisiert die Groß- und Kleinschreibung über alle Quellen hinweg.
Erstellung von Locale-Auswahloberflächen
Wenn Sie Dropdown-Menüs oder Auswahloberflächen erstellen, normalisieren Sie die Locale-Bezeichner für die Anzeige:
function buildLocaleOptions(locales) {
const normalized = Intl.getCanonicalLocales(locales);
return normalized.map(locale => {
const localeObj = new Intl.Locale(locale);
const displayNames = new Intl.DisplayNames([locale], {
type: "language"
});
return {
value: locale,
label: displayNames.of(localeObj.language)
};
});
}
const options = buildLocaleOptions(["EN-us", "fr-FR", "DE-de"]);
console.log(options);
// [
// { value: "en-US", label: "English" },
// { value: "fr-FR", label: "French" },
// { value: "de-DE", label: "German" }
// ]
Die normalisierten Werte bieten konsistente Bezeichner für Formularübermittlungen.
Validierung von Konfigurationsdateien
Wenn Sie Locale-Bezeichner aus Konfigurationsdateien laden, normalisieren Sie diese während der Initialisierung:
function loadLocaleConfig(config) {
const validatedConfig = {
defaultLocale: null,
supportedLocales: []
};
try {
validatedConfig.defaultLocale = Intl.getCanonicalLocales(
config.defaultLocale
)[0];
} catch (error) {
console.error("Invalid default locale:", config.defaultLocale);
validatedConfig.defaultLocale = "en-US";
}
config.supportedLocales.forEach(locale => {
try {
const normalized = Intl.getCanonicalLocales(locale)[0];
validatedConfig.supportedLocales.push(normalized);
} catch (error) {
console.warn("Skipping invalid locale:", locale);
}
});
return validatedConfig;
}
const config = {
defaultLocale: "en-us",
supportedLocales: ["EN-us", "fr-FR", "invalid", "de-DE"]
};
const validated = loadLocaleConfig(config);
console.log(validated);
// {
// defaultLocale: "en-US",
// supportedLocales: ["en-US", "fr-FR", "de-DE"]
// }
Dadurch werden Konfigurationsfehler frühzeitig erkannt und sichergestellt, dass Ihre Anwendung gültige, normalisierte Bezeichner verwendet.
Normalisierung und Locale-Matching
Die Normalisierung ist wichtig für Locale-Matching-Algorithmen. Wenn Sie die beste Locale-Übereinstimmung für eine Benutzerpräferenz finden, vergleichen Sie die normalisierten Formen:
function findBestMatch(userPreference, availableLocales) {
const normalizedPreference = Intl.getCanonicalLocales(userPreference)[0];
const normalizedAvailable = Intl.getCanonicalLocales(availableLocales);
if (normalizedAvailable.includes(normalizedPreference)) {
return normalizedPreference;
}
const preferenceLocale = new Intl.Locale(normalizedPreference);
const languageMatch = normalizedAvailable.find(available => {
const availableLocale = new Intl.Locale(available);
return availableLocale.language === preferenceLocale.language;
});
if (languageMatch) {
return languageMatch;
}
return normalizedAvailable[0];
}
const available = ["en-us", "fr-FR", "DE-de"];
console.log(findBestMatch("EN-GB", available));
// "en-US"
Die Normalisierung stellt sicher, dass die Matching-Logik unabhängig von der Groß- und Kleinschreibung der Eingabe korrekt funktioniert.
Normalisierung ändert nicht die Bedeutung
Die Normalisierung betrifft nur die Darstellung eines Locale-Identifiers. Sie ändert nicht, welche Sprache, Schrift oder Region der Identifier repräsentiert.
const locale1 = new Intl.Locale("en-us");
const locale2 = new Intl.Locale("EN-US");
console.log(locale1.language === locale2.language);
// true
console.log(locale1.region === locale2.region);
// true
console.log(locale1.toString() === locale2.toString());
// true
Beide Identifier beziehen sich auf amerikanisches Englisch. Die Normalisierung stellt lediglich sicher, dass sie auf die gleiche Weise geschrieben werden.
Dies unterscheidet sich von Operationen wie maximize() und minimize(), die Komponenten hinzufügen oder entfernen und die Spezifität des Identifiers ändern können.
Browser-Unterstützung
Die Methode Intl.getCanonicalLocales() funktioniert in allen modernen Browsern. Chrome, Firefox, Safari und Edge bieten vollständige Unterstützung.
Node.js unterstützt Intl.getCanonicalLocales() ab Version 9, mit vollständiger Unterstützung in Version 10 und später.
Der Konstruktor Intl.Locale und sein Normalisierungsverhalten funktionieren in allen Browsern, die die API Intl.Locale unterstützen. Dazu gehören moderne Versionen von Chrome, Firefox, Safari und Edge.
Zusammenfassung
Die Normalisierung konvertiert Locale-Identifier in ihre kanonische Form, indem sie standardisierte Groß- und Kleinschreibungsregeln anwendet und Extension-Keywords sortiert. Dies erzeugt konsistente Darstellungen, die Sie zuverlässig speichern, vergleichen und anzeigen können.
Wichtige Konzepte:
- Die kanonische Form verwendet Kleinbuchstaben für Sprachen, Title Case für Schriften und Großbuchstaben für Regionen
- Extension-Keywords werden in der kanonischen Form alphabetisch sortiert
- Die Methode
Intl.getCanonicalLocales()normalisiert Identifier und entfernt Duplikate - Der Konstruktor
Intl.Localeerzeugt ebenfalls normalisierte Ausgaben - Die Normalisierung ändert nicht die Bedeutung eines Locale-Identifiers
- Verwenden Sie normalisierte Identifier für Speicherung, Vergleich und Anzeige
Die Normalisierung ist eine grundlegende Operation für jede Anwendung, die mit Locale-Identifiern arbeitet. Sie verhindert Fehler, die durch inkonsistente Groß- und Kleinschreibung verursacht werden, und stellt sicher, dass Ihre Internationalisierungslogik Locale-Identifier zuverlässig verarbeitet.