Entraînez-vous à travailler avec des paires de substitution Unicode en Java

Après un petit examen des codes de caractères, j'ai réalisé que je n'avais jamais été préoccupé par les paires de substituts Unicode. Donc, je me suis exercé à assembler des chaînes de caractères de paires de substitution et à compter le nombre de caractères en Java, que je gère également au travail.

Jusqu'à Java 1.4, les paires de substitution n'étaient pas prises en compte, mais dans la version 1.5, une API qui considère les paires de substitution a été ajoutée. Par conséquent, dans le code de test ci-dessus, nous essayons d'appeler l'API jusqu'à la série 1.4 et l'API ajoutée dans la version 1.5 et de comparer le comportement.

Tout d'abord, exprimons une paire de substitution avec le type char. Le substitut supérieur et le substitut inférieur sont séparés en tant que variables de type char distinctes et incorporés dans le tableau.

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");

Ensuite, essayez de copier la chaîne en utilisant String.length () ou String.charAt (), qui ne prend pas en compte les paires de substitution. En regardant le dernier ʻassertEquals () `, il correspond à la chaîne générée à partir de ʻint [] ʻ dans laquelle la paire de substitution est divisée. Vous pouvez voir comment le substitut supérieur et le substitut inférieur sont traités comme des caractères indépendants et copiés.

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 });

Essayez maintenant d'utiliser String.codePointCount () et String.codePointAt () pour considérer les paires de substitution. Si vous regardez le dernier ʻassertEquals () `, ce sera le même que le caractère cible de la paire de substitution exprimé en points de code hexadécimaux. Vous pouvez vérifier comment la paire de substitution est gérée en la comptant comme un caractère.

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 });

référence:

Recommended Posts

Entraînez-vous à travailler avec des paires de substitution Unicode en Java
Gérez d'énormes JSON avec Java Lambda
Résolution du problème lorsque Azure Functions a cessé de fonctionner en Java
Agrégation et analyse de journaux (utilisation d'AWS Athena en Java)
Analyse morphologique en Java avec Kuromoji
Tweak Markdown avec Java flexmark-java
Méthode de concurrence en Java avec exemple de base
Lire le fichier xlsx en Java avec Selenium
Diviser une chaîne avec ". (Dot)" en Java
Lire une chaîne dans un fichier PDF avec Java
Créer un CSR avec des informations étendues en Java
Outil GUI refactorisé réalisé avec Java8 + JavaFX en 2016
La solution pour NetBeans 8.2 ne fonctionne pas dans l'environnement Java 9
[JAVA] [Spring] [MyBatis] Utiliser IN () avec SQL Builder
Crypter / décrypter avec AES256 en PHP et Java
Programmation utilisant le type de somme directe en Java (news)
S'entendre avec les conteneurs Java dans Cloud Run
Partition en Java
Changements dans Java 11
Janken à Java
java pratique partie 1
Taux circonférentiel à Java
FizzBuzz en Java
Comment appeler des fonctions en bloc avec la réflexion Java
Inclure l'image dans le fichier jar avec la méthode statique java
Remarquez un problème multi-thread lorsque vous travaillez avec Java Servlet
Implémentez rapidement singleton avec enum en Java
Sortie true avec if (a == 1 && a == 2 && a == 3) en Java (identifiant invisible)
Vérifiez la couverture avec Codecov dans la configuration Java + Gradle + Wercker