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