Was macht String.Normalize von .NET?

74

Der MSDN-Artikel zu String.Normalize besagt einfach:

Gibt eine neue Zeichenfolge zurück, deren binäre Darstellung in einer bestimmten Unicode-Normalisierungsform vorliegt.

Und manchmal unter Bezugnahme auf eine "Unicode-Normalisierungsform C."

Ich frage mich nur, was bedeutet das? Wie ist diese Funktion in realen Situationen nützlich?

GeReV
quelle
2
+1 nette Frage, neugierig darauf.
Adam Houldsworth

Antworten:

52

Es stellt sicher, dass Unicode-Zeichenfolgen auf Gleichheit verglichen werden können (auch wenn sie unterschiedliche Unicode-Codierungen verwenden).

Aus dem Unicode-Standardanhang Nr. 15 :

Im Wesentlichen ordnet der Unicode-Normalisierungsalgorithmus alle Kombinationsmarken in einer bestimmten Reihenfolge an und verwendet Regeln für die Zerlegung und Komposition, um jede Zeichenfolge in eine der Unicode-Normalisierungsformen umzuwandeln. Ein binärer Vergleich der transformierten Zeichenfolgen bestimmt dann die Äquivalenz.

Oded
quelle
Hervorragende Antwort. Vorausgesetzt, der Link ist großartig!
GeReV
72

Ein Unterschied zwischen Form C und Form D besteht darin, wie Buchstaben mit Akzenten dargestellt werden: Form C verwendet einen einzelnen Codepunkt mit Buchstaben und Akzenten, während Form D diesen in einen Buchstaben und einen Akzent unterteilt.

Beispielsweise kann ein "à" der Codepunkt 224 ("lateinischer Kleinbuchstabe A mit Grab") oder der Codepunkt 97 ("lateinischer Kleinbuchstabe A") sein, gefolgt vom Codepunkt 786 ("Kombinieren des Grabakzents"). Ein char-by-char-Vergleich würde diese als unterschiedlich ansehen. Durch die Normalisierung ist der Vergleich erfolgreich.

Ein Nebeneffekt ist, dass dies das einfache Erstellen einer Methode zum Entfernen von Akzenten ermöglicht.

public static string RemoveAccents(string input)
{
    return new string(input
        .Normalize(System.Text.NormalizationForm.FormD)
        .ToCharArray()
        .Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
        .ToArray());
    // the normalization to FormD splits accented letters in letters+accents
    // the rest removes those accents (and other non-spacing characters)
    // and creates a new string from the remaining chars
}
Hans Keing
quelle
6

In Unicode kann ein (zusammengesetztes) Zeichen entweder einen eindeutigen Codepunkt oder eine Folge von Codepunkten haben, die aus dem Basiszeichen und seinen Akzenten besteht.

Wikipedia listet als Beispiel Vietnamesisch ế (U + 1EBF) und seine zerlegte Folge U + 0065 (e) U + 0302 (Zirkumflex-Akzent) U + 0301 (akuter Akzent) auf.

string.Normalize () konvertiert zwischen den 4 Normalformen, die ein String in Unicode codieren kann.

devio
quelle
5

Dieser Link hat eine gute Erklärung:

http://unicode.org/reports/tr15/#Norm_Forms

Soweit ich vermuten kann, können Sie zwei Unicode-Zeichenfolgen auf Gleichheit vergleichen.

Adam Houldsworth
quelle