Okay, in .Net und C # sind alle Zeichenfolgen als UTF-16LE codiert . A string
wird als Folge von Zeichen gespeichert. Jedes char
kapselt die Speicherung von 2 Bytes oder 16 Bits.
Was wir "auf Papier oder Bildschirm" als einen einzelnen Buchstaben, ein Zeichen, eine Glyphe, ein Symbol oder ein Interpunktionszeichen sehen, kann als ein einzelnes Textelement betrachtet werden. Wie in Unicode Standard Annex # 29 UNICODE TEXT SEGMENTATION beschrieben , wird jedes Textelement durch einen oder mehrere Codepunkte dargestellt. Eine vollständige Liste der Codes finden Sie hier .
Jeder Codepunkt muss für die interne Darstellung durch einen Computer binär codiert werden. Wie angegeben, char
speichert jeder 2 Bytes. Codepunkte an oder unter U+FFFF
können in einem einzigen gespeichert werden char
. Die obigen U+FFFF
Codepunkte werden als Ersatzpaar gespeichert, wobei zwei Zeichen verwendet werden, um einen einzelnen Codepunkt darzustellen.
Wenn wir wissen, was wir jetzt ableiten können, kann ein Textelement als eines char
, als Ersatzpaar aus zwei Zeichen oder, wenn das Textelement durch mehrere Codepunkte dargestellt wird, als Kombination aus einzelnen Zeichen und Ersatzpaaren gespeichert werden. Als ob das nicht kompliziert genug wäre, können einige Textelemente durch verschiedene Kombinationen von Codepunkten dargestellt werden, wie in Unicode Standard Annex # 15, UNICODE NORMALIZATION FORMS beschrieben .
Zwischenspiel
Zeichenfolgen, die beim Rendern gleich aussehen, können also aus einer anderen Kombination von Zeichen bestehen. Ein ordinaler (Byte für Byte) Vergleich zweier solcher Zeichenfolgen würde einen Unterschied feststellen. Dies kann unerwartet oder unerwünscht sein.
Sie können .NET-Zeichenfolgen neu codieren. so dass sie das gleiche Normalisierungsformular verwenden. Nach der Normalisierung werden zwei Zeichenfolgen mit denselben Textelementen auf dieselbe Weise codiert. Verwenden Sie dazu die Funktion string.Normalize . Denken Sie jedoch daran, dass einige verschiedene Textelemente einander ähnlich sehen. : -s
Was bedeutet das alles in Bezug auf die Frage? Das '𠈓'
Textelement wird durch die einzelne Code Point U + 20213 cjk Unified Ideographs-Erweiterung b dargestellt . Dies bedeutet, dass es nicht als einzelnes char
Zeichen codiert werden kann und als Ersatzpaar mit zwei Zeichen codiert werden muss. Deshalb string b
ist man char
länger so string a
.
Wenn Sie die Anzahl der Textelemente in a zuverlässig zählen müssen (siehe Einschränkung) string
, sollten Sie die
System.Globalization.StringInfo
Klasse wie folgt verwenden.
using System.Globalization;
string a = "abc";
string b = "A𠈓C";
Console.WriteLine("Length a = {0}", new StringInfo(a).LengthInTextElements);
Console.WriteLine("Length b = {0}", new StringInfo(b).LengthInTextElements);
die Ausgabe geben,
"Length a = 3"
"Length b = 3"
wie erwartet.
Vorbehalt
Die .NET-Implementierung der Unicode-Textsegmentierung in den Klassen StringInfo
und TextElementEnumerator
sollte im Allgemeinen nützlich sein und in den meisten Fällen eine Antwort liefern, die der Aufrufer erwartet. Wie in Unicode Standard Annex # 29 angegeben, "kann das Ziel der Übereinstimmung der Benutzerwahrnehmungen nicht immer genau erreicht werden, da der Text allein nicht immer genügend Informationen enthält, um Grenzen eindeutig zu bestimmen."