2010-02-23 20 views
9

Wenn ich ein Byte-Array habe, das UTF8-Inhalt enthält, wie würde ich es analysieren? Gibt es Delimiter-Bytes, die ich abspalten kann, um jedes Zeichen zu erhalten?Gibt es Begrenzerbytes für UTF8-Zeichen?

+0

Seien Sie vorsichtig mit ungültigen Eingaben, stellen Sie sicher, dass Ihr Code nicht etwas Schlechtes tut, wie ein Pufferüberlauf, wenn eine Sequenz zum Beispiel über 4 Bytes kommt. –

+0

Sobald Sie die notwendigen Bit-Picking getan haben, erhalten Sie am Ende eine Reihe von Zeichen von 1 bis 4 Bytes lang; was wirst du damit machen? Warum entschlüsselst du es nicht und arbeitest an den resultierenden Unicode-Zeichen? –

+0

@JohnMachin in meinem Fall ist der "Haufen von Zeichen" zu groß, um auf einmal verarbeitet zu werden, und mein Code sucht nach einem sicheren Byte-Offset, um die Daten in kleinere Stücke zu zerlegen, mit denen individuell gearbeitet werden kann. –

Antwort

13

einen Blick hier nehmen ...

http://en.wikipedia.org/wiki/UTF-8

Wenn Sie schauen, um die Grenze zwischen Zeichen zu identifizieren, was Sie brauchen, ist in der Tabelle unter „Beschreibung“.

Die einzige Möglichkeit, ein hohes Bit Null zu erhalten, ist die ASCII-Teilmenge 0..127, die in einem einzigen Byte codiert ist. Alle Nicht-ASCII-Codepunkte haben ein zweites Byte mit "10" in den höchsten zwei Bits. Das führende Byte eines Codepoints hat das nie - seine hohen Bits geben die Anzahl der Bytes an, aber es gibt eine gewisse Redundanz - Sie könnten genauso auf das nächste Byte achten, das nicht die "10" hat, um den nächsten Codepunkt anzuzeigen.

0xxxxxxx : ASCII 
10xxxxxx : 2nd, 3rd or 4th byte of code 
11xxxxxx : 1st byte of code, further high bits indicating number of bytes 

Ein Codepunkt in Unicode ist nicht unbedingt dasselbe wie ein Zeichen. Es gibt Modifikator-Codepunkte (wie zum Beispiel Akzente).

+0

Was ist mit Emoji-Variationssequenzen? Zum Beispiel, wenn das Zeichen 'U + 1F469' (in der binären' 11110000 10011111 10010001 10101001') auf sich selbst ist, erhalten Sie das "Frau" Emoji. Wenn jedoch "U + 1F3FD" gefolgt wird (binär "11110000 10011111 10001111 10111101"), dann wird es eine Frau mit brauner Haut sein. Wie können Sie diese Grenze sicher erkennen, um zu vermeiden, dass UTF-8-Bytes zwischen den beiden gebrochen werden? Beide Codepoints sind einzeln gültig (letzteres wird unter OS X als braunes Quadrat dargestellt), aber die Benutzer würden nicht erwarten, dass sie aufgeteilt werden. –

+0

@AbhiBeckert - Sie denken auf der falschen Ebene. UTF-8 definiert oder interessiert sich nicht dafür, wie Sequenzen von Unicode-Codepunkten zueinander stehen. Zuerst übersetzen Sie UTF-8 (oder andere Codierungen) in einen Unicode-Codepoint-Stream, und Sie interpretieren dies. Ich kenne keine Unicode-spezifischen Details, aber eine allgemeine Herangehensweise an das Problem der Handhabung von Modifikator-Codepunkten ist die gleiche wie die Erkennung von Schlüsselwörtern und anderen Token in einem Programmiersprachen-Tokenizer. Es gibt wahrscheinlich einen besseren Unicode-spezifischen Weg, aber ich weiß es nicht und auf jeden Fall sollten Sie eine separate Frage stellen. – Steve314

+0

Ich versuche, "die Grenze zwischen den Zeichen" zu identifizieren, wobei ein "Zeichen" eine einzelne Glyphe ist, die auf den Bildschirm gezeichnet wird, was genau die Frage ist, die Sie beantworten, soweit ich sehen kann.Ich spalte eine große (möglicherweise Gigabyte) Menge von utf-8 Daten in kleinere Stücke (Dutzende von Bytes Länge), die auf den Bildschirm einzeln gezeichnet werden, und dies wird still brechen, wenn die Bytes getrennt sind, wie Sie in Ihrem vorschlagen Antworten. –

0

Bytes, bei denen das erste Bit auf 0 gesetzt ist, sind normale ASCII-Zeichen. Bytes, deren erstes Bit auf 1 gesetzt ist, sind Teil eines UTF-8-Zeichens.

Das erste Byte in jedem UTF-8-Zeichen hat sein zweites Bit auf 1 gesetzt, so dass das Byte die höchstwertigen Bits 11 enthält. Jedes folgende Byte, das zu demselben UTF-8-Zeichen gehört, beginnt stattdessen mit 10.

Das erste Byte jedes UTF-8-Zeichens gibt zusätzlich an, wie viele der folgenden Bytes zu dem Zeichen gehören, abhängig von der Anzahl der Bits, die in den höchstwertigen Bits dieses Bytes auf 1 gesetzt sind. Weitere Informationen finden Sie unter Wikipedia page für UTF-8.

+0

"UTF-8-Zeichen" ist eine falsche Bezeichnung. Sie scheinen sich auf eine Sequenz von zwei bis vier Bytes zu beziehen, die ein Nicht-ASCII-Zeichen darstellt. Wenn es darum geht, Unicode zu verstehen, glaube ich, dass das richtige Vokabular die halbe Miete ist. –