Vergleicht man zwei Bytes [] von utf-8-codierten Strings mit dem Vergleich zweier Unicode-Strings?

8

Ich habe das im Wikipedia-Artikel zu utf-8 gefunden:

  

Das Sortieren von UTF-8-Strings als Arrays von Bytes ohne Vorzeichen führt zu denselben Ergebnissen wie das Sortieren auf Basis von Unicode-Codepunkten.

Das würde mich dazu bringen zu glauben, dass zu Vergleichszwecken (Sortieren, binäre Suche usw.) das Vergleichen von zwei Byte-Arrays (dh byteweise wie memcmp) von utf-8-codierten Strings die gleichen Ergebnisse liefern würde wie der Vergleich von tatsächliche Unicode-Zeichenfolgen.

Stimmt das?

    
Eloff 13.08.2010, 16:44
quelle

5 Antworten

5

Es hängt davon ab, was Sie meinen, indem Sie "die tatsächlichen Unicode-Zeichenfolgen vergleichen".

Wenn Sie nur die Codepunkte (als 32-Bit-Nummern) anstelle der UTF-8-kodierten Codepunkte vergleichen, lautet die Antwort ja: Das ergibt die gleichen Ergebnisse. Die Zuordnung von Codepunkten zu UTF-8-codierten Bytes erfolgt eins zu eins.

Wenn Sie einen korrekten Unicode-String-Vergleich durchführen wollen, anstatt des byteweisen Vergleichs des UTF-8, lautet die Antwort nein. In Unicode kann es verschiedene Möglichkeiten geben, dasselbe Zeichen darzustellen. Zum Beispiel kann é auf (mindestens) zwei Arten dargestellt werden:

  • U+00e9 (LATIN SMALL LETTER E WITH ACUTE) oder
  • U+0065 (LATIN SMALL LETTER E) gefolgt von U+0301 (COMBINING ACUTE ACCENT) .

Eine korrekt geschriebene Unicode-Vergleichsfunktion wird diese beiden als identisch betrachten.

    
Thomas 13.08.2010, 16:50
quelle
5

Ja, vorausgesetzt, es gibt eine Eins-zu-Eins-Zuordnung zwischen den Bytes der Sequenzen in der UTF-8-Codierung und den Unicode-Codepunkten.

Es gibt jedoch eine Möglichkeit, Unicode-Strings zu vergleichen, abgesehen von den Rohcodepunkten. Wenn Sie nur Codepunkte - oder UTF-8-Bytes - als Zahlen betrachten, vermissen Sie kulturspezifische Vergleichslogik.

Um den Vergleich und die korrekte Sortierung für eine bestimmte Kultur in .NET zu implementieren, sollten Sie die Standard-String-Vergleichsfunktionen verwenden.

    
Tim Robinson 13.08.2010 16:48
quelle
5

Es ist dasselbe wie ein Codepunkt für den Codepunktvergleich, also einen, der keine Fallfaltung, kulturelle Ordnungen, Komposition oder irgendetwas anderes als den Unicode-Wert berücksichtigt.

Das ist ziemlich nutzlos, wenn Sie Strings als ein Stück lesbaren Text betrachten, aber manchmal möchten Sie einfach die Strings in eine Ordnung bringen, wie einige Algorithmen (binäre Suche wie Sie) sagen) brauchen eine konsistente Reihenfolge, aber die Details dieser konsistenten Reihenfolge ist nicht signifikant.

Es ist jedoch wichtig zu beachten, dass der ordinale Vergleich von Strings, die von .NET angeboten werden, auf dem intern verwendeten UTF-16 funktioniert, wobei nicht die Reihenfolge der Codepunkte verwaltet. Wenn wir eine Zeichenkette nur mit dem Zeichen U + FF61 und einer Zeichenkette mit nur dem Zeichen U + 10002 vergleichen, speichert .NET diese als Ersatzpaare von 0xD800 und 0XDC02.

Daher:

%Vor%

und

%Vor%

Beide Rückgabewerte sind größer als Null, obwohl ersterer einen niedrigeren Codepunktwert als letzterer hat (ich habe die \ U-Form verwendet und nicht die \ u-Form, um das deutlicher zu machen).

Wenn Sie unter "die tatsächlichen Unicode-Strings" die .NET UTF-16-Strings verstehen, dann lautet die Antwort auf Ihre Frage "Nein", aus dem entgegengesetzten Grund zu dem, was dazu führte, dass Sie denken, dass es funktioniert.

    
Jon Hanna 13.08.2010 17:03
quelle
3

Nein, ist es nicht.

Beispielsweise kann als einzelner Codepunkt ( U+00C0 LATIN CAPITAL LETTER A MIT GRAVE) oder als zwei Codepunkte ( U+0041 LATIN CAPITAL LETTER A U+0300 KOMBINIEREND GRAVE ACCENT) geschrieben werden.

Beide Darstellungen sollten gleich sein, aber unterschiedliche Bytecodierungen haben.

    
SLaks 13.08.2010 16:47
quelle
0
  

Ich habe das im Wikipedia-Artikel zu utf-8 gefunden:

     
    

Das Sortieren von UTF-8-Strings als Arrays von Bytes ohne Vorzeichen führt zu denselben Ergebnissen wie das Sortieren auf Basis von Unicode-Codepunkten.

  
     

Das würde mich dazu bringen zu glauben, dass zu Vergleichszwecken (Sortieren, binäre Suche usw.) das Vergleichen von zwei Byte-Arrays (dh byteweise wie memcmp) von utf-8-codierten Strings die gleichen Ergebnisse liefern würde wie der Vergleich von tatsächliche Unicode-Zeichenfolgen.

Das hängt davon ab, was Sie mit "tatsächlichen Unicode-Strings" meinen und was Sie mit "Vergleichen" meinen. In .NET Framework sind Zeichenfolgen in der UTF-16-Form von Unicode. Ein einfacher binärer Vergleich zwischen UTF-16-Strings führt zu einer anderen Sortierreihenfolge als der gleiche Vergleich zwischen UTF-8 und UTF-32 (die Codepunkt-Version, auf die im Zitat verwiesen wird).

Aber ein binärer Vergleich von irgendwelchen dieser Dinge ist nicht sehr nützlich. Sie sollten die integrierten kultursensitiven Vergleiche verwenden. Dies liegt daran, dass zwei in jeder Hinsicht identische Zeichenfolgen aus verschiedenen Sequenzen von Codepunkten konstruiert werden können. Die integrierten Vergleiche berücksichtigen diese Dinge.

    
Jeffrey L Whitledge 13.08.2010 17:00
quelle

Tags und Links