Üben Sie die Arbeit mit Unicode-Ersatzpaaren in Java

Nach einer kleinen Überprüfung des Zeichencodes wurde mir klar, dass ich mir nie Sorgen um Unicode-Ersatzpaare gemacht hatte. Also habe ich geübt, Ersatzpaar-Zeichenketten zusammenzusetzen und die Anzahl der Zeichen in Java zu zählen, die ich auch bei der Arbeit verarbeite.

Bis Java 1.4 wurden Ersatzpaare nicht berücksichtigt, aber in 1.5 wurde eine API hinzugefügt, die Ersatzpaare berücksichtigt. Daher versuchen wir im obigen Testcode, die API bis zur 1.4-Serie und die in 1.5 hinzugefügte API aufzurufen und das Verhalten zu vergleichen.

Lassen Sie uns zunächst ein Ersatzpaar mit dem Typ char ausdrücken. Der obere Ersatz und der untere Ersatz werden als separate Zeichenvariablen getrennt und in das Array aufgenommen.

char c1 = '\u3042'; // HIRAGANA LETTER A, cp=12354
char c2 = '\uD842'; // tuchi-yoshi (high), cp=134071
char c3 = '\uDFB7'; // tuchi-yoshi (low), cp=134071
char c4 = '\u30D5'; // katakana fu, cp=12501
char c5 = '\u309A'; // handakuten, cp=12442
char c6 = '\uD842'; // kuchi + shichi (high), cp=134047
char c7 = '\uDF9F'; // kuchi + shichi (low), cp=134047
String s = new String(new char[] { c1, c2, c3, c4, c5, c6, c7 });
assertEquals(s, "\u3042\uD842\uDFB7\u30D5\u309A\uD842\uDF9F");

Versuchen Sie dann, die Zeichenfolge mit "String.length ()" oder "String.charAt ()" zu kopieren, wobei keine Ersatzpaare berücksichtigt werden. Wenn man sich das endgültige "assertEquals ()" ansieht, stimmt es mit der aus "int []" generierten Zeichenfolge mit der Aufteilung des Ersatzpaars überein. Sie können sehen, wie der obere und der untere Ersatz als unabhängige Zeichen behandelt und kopiert werden.

int len = s.length();
assertEquals(len, 7); // ignores surrogate pair :P
int[] actualCps = new int[len];
for (int i = 0; i < len; i++) {
    char c = s.charAt(i);
    actualCps[i] = (int) c;
}
// Ignores surrogate pairs... :(
// BUT JavaScript unicode escape in browser accepts this format...:(
assertEquals(actualCps, new int[] { 0x3042, 0xD842, 0xDFB7, 0x30D5, 0x309A, 0xD842, 0xDF9F });

Versuchen Sie nun, String.codePointCount () und String.codePointAt () zu verwenden, um Ersatzpaare zu berücksichtigen. Wenn Sie sich das letzte "assertEquals ()" ansehen, werden Sie feststellen, dass das gepaarte Ersatzzeichen mit der hexadezimalen Zeichenfolge von Unicode-Codepunkten identisch ist. Sie können überprüfen, wie das Ersatzpaar behandelt wird, indem Sie es als ein Zeichen zählen.

int countOfCp = s.codePointCount(0, len);
assertEquals(countOfCp, 5); // GOOD.

actualCps = new int[countOfCp];
for (int i = 0, j = 0, cp; i < len; i += Character.charCount(cp)) {
    cp = s.codePointAt(i);
    actualCps[j++] = cp;
}
// GOOD.
assertEquals(actualCps, new int[] { 0x3042, 0x20BB7, 0x30D5, 0x309A, 0x20B9F });

Referenz:

Recommended Posts

Üben Sie die Arbeit mit Unicode-Ersatzpaaren in Java
Behandeln Sie große JSON mit Java Lambda
Adressiert, da Azure-Funktionen in Java nicht mehr funktionieren
Protokollaggregation und -analyse (Arbeiten mit AWS Athena in Java)
Morphologische Analyse in Java mit Kuromoji
Tweak Markdown mit Java Flexmark-Java
Parallelitätsmethode in Java mit grundlegendem Beispiel
Lesen Sie die xlsx-Datei in Java mit Selenium
Teilen Sie eine Zeichenfolge in Java mit ". (Dot)"
Lesen Sie eine Zeichenfolge in einer PDF-Datei mit Java
Erstellen Sie eine CSR mit erweiterten Informationen in Java
Überarbeitetes GUI-Tool, das 2016 mit Java8 + JavaFX erstellt wurde
Lösung für NetBeans 8.2 funktioniert nicht in Java 9-Umgebung
[JAVA] [Spring] [MyBatis] Verwenden Sie IN () mit SQL Builder
Verschlüsseln / Entschlüsseln mit AES256 in PHP und Java
Programmierung mit dem direkten Summentyp in Java (Nachrichten)
Kommen Sie mit Java-Containern in Cloud Run zurecht
Partisierung in Java
Änderungen in Java 11
Janken in Java
Java-Übung Teil 1
Umfangsrate in Java
FizzBuzz in Java
Aufrufen von Funktionen in großen Mengen mit Java Reflection
Fügen Sie das Bild mit der statischen Java-Methode in die JAR-Datei ein
Beachten Sie das Multithread-Problem, wenn Sie mit Java Servlet arbeiten
Implementieren Sie Singleton mit Enum schnell in Java
Ausgabe true mit if (a == 1 && a == 2 && a == 3) in Java (Invisible Identifier)
Überprüfen Sie die Abdeckung mit Codecov in der Java + Gradle + Wercker-Konfiguration