Je lisais la documentation pour StringBuffer
, en particulier la méthode reverse () . Cette documentation mentionne quelque chose sur les paires de substitution . Qu'est-ce qu'une paire de substitution dans ce contexte? Et que sont les substituts bas et élevés ?
java
unicode
utf-16
surrogate-pairs
Raymond
la source
la source
String
s soient constitués, pas seulement des unités de caractères. Dommage que Java ne vous permette pas d'utiliser OO pour résoudre ce problème, mais laString
classe et lesStringBuffer
classes ont étéfinal
dimensionnées. Dites, n'est-ce pas un euphémisme pour tué? :)Réponses:
Le terme «paire de substitution» fait référence à un moyen de coder des caractères Unicode avec des points de code élevés dans le schéma de codage UTF-16.
Dans le codage de caractères Unicode, les caractères sont mappés à des valeurs comprises entre 0x0 et 0x10FFFF.
En interne, Java utilise le schéma de codage UTF-16 pour stocker des chaînes de texte Unicode. En UTF-16, des unités de code 16 bits (deux octets) sont utilisées. Étant donné que 16 bits ne peuvent contenir que la plage de caractères de 0x0 à 0xFFFF, une complexité supplémentaire est utilisée pour stocker les valeurs au-dessus de cette plage (0x10000 à 0x10FFFF). Cela se fait à l'aide de paires d'unités de code appelées substituts.
Les unités de code de substitution sont dans deux plages appelées «substituts élevés» et «substituts faibles», selon qu'elles sont autorisées au début ou à la fin de la séquence à deux unités de code.
la source
Les premières versions de Java représentaient les caractères Unicode à l'aide du type de données char 16 bits. Cette conception avait du sens à l'époque, car tous les caractères Unicode avaient des valeurs inférieures à 65 535 (0xFFFF) et pouvaient être représentés en 16 bits. Plus tard, cependant, Unicode a augmenté la valeur maximale à 1 114 111 (0 x 10FFFF). Parce que les valeurs 16 bits étaient trop petites pour représenter tous les caractères Unicode dans Unicode version 3.1, des valeurs 32 bits - appelées points de code - ont été adoptées pour le schéma de codage UTF-32. Mais les valeurs 16 bits sont préférées aux valeurs 32 bits pour une utilisation efficace de la mémoire, c'est pourquoi Unicode a introduit une nouvelle conception pour permettre l'utilisation continue des valeurs 16 bits. Cette conception, adoptée dans le schéma de codage UTF-16, attribue 1024 valeurs à des substituts élevés 16 bits (dans la plage U + D800 à U + DBFF) et 1024 autres valeurs à des substituts faibles 16 bits (dans la plage U + DC00 à U + DFFF).
la source
Ce que dit cette documentation, c'est que les chaînes UTF-16 non valides peuvent devenir valides après l'appel de la
reverse
méthode car elles peuvent être les inversions de chaînes valides. Une paire de substitution (discutée ici ) est une paire de valeurs 16 bits en UTF-16 qui codent un seul point de code Unicode; les substituts bas et haut sont les deux moitiés de ce codage.la source
Ajout d'informations supplémentaires aux réponses ci-dessus à partir de ce post.
Testé en Java-12, devrait fonctionner dans toutes les versions Java supérieures à 5.
Comme mentionné ici: https://stackoverflow.com/a/47505451/2987755 ,
quel que soit le caractère (dont Unicode est au-dessus de U + FFFF) est représenté comme une paire de substitution, que Java stocke comme une paire de valeurs de caractères, c'est-à-dire l'unique Unicode Le caractère est représenté par deux caractères Java adjacents.
Comme nous pouvons le voir dans l'exemple suivant.
1. Longueur:
2. Égalité:
Représentez "🌉" en chaîne en utilisant Unicode
\ud83c\udf09
comme ci-dessous et vérifiez l'égalité.Java ne prend pas en charge UTF-32
3. Vous pouvez convertir le caractère Unicode en chaîne Java
4. String.substring () ne prend pas en compte les caractères supplémentaires
Pour résoudre ce problème, nous pouvons utiliser
String.offsetByCodePoints(int index, int codePointOffset)
5. Faire Itère Unicode avec BreakIterator
6. Tri des chaînes avec Unicode java.text.Collator
7. de caractère
toUpperCase()
, lestoLowerCase()
méthodes ne doivent pas être utilisés, à la place, en majuscules l' utilisation de chaînes et minuscules des paramètres régionaux spécifiques.8.
Character.isLetter(char ch)
ne prend pas en charge, mieux utiliséCharacter.isLetter(int codePoint)
, pour chaquemethodName(char ch)
méthode de la classe Character dont le typemethodName(int codePoint)
peut gérer les caractères supplémentaires.9. Indiquez charset dans
String.getBytes()
, la conversion d'octets à cordesInputStreamReader
,OutputStreamWriter
Réf:
https://coolsymbol.com/emojis/emoji-for-copy-and-paste.html#objects
https://www.online-toolz.com/tools/text-unicode-entities-convertor.php
https: //www.ibm.com/developerworks/library/j-unicode/index.html
https://www.oracle.com/technetwork/articles/javaee/supplementary-142654.html
Plus d'informations sur l'exemple image1 image2
Autres termes à explorer: Normalisation , BiDi
la source
Les paires de substitution font référence à la façon dont UTF-16 codifie certains caractères, voir http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFF
la source
Petite préface
Avant la version 3.1, le codage 8 bits, connu sous le nom UTF-8, était principalement utilisé et le codage 16 bits, appelé UCS-2 ou «Universal Character Set codé en 2 octets». UTF-8 encode les points Unicode comme une séquence de blocs de 1 octet, tandis que UCS-2 prend toujours 2 octets:
A = 41 - un bloc de 8 bits avec UTF-8
A = 0041 - un bloc de 16 bits avec UCS-2
Ω = CE A9 - deux blocs de 8 bits avec UTF-8
Ω = 03A9 - un bloc de 16 bits avec UCS-2
Problème
Le consortium a pensé que 16 bits suffiraient pour couvrir n'importe quel langage lisible par l'homme, ce qui donne 2 ^ 16 = 65536 valeurs de code possibles. Cela était vrai pour l'avion 0, également connu sous le nom de BPM ou Basic Multilingual Plane, qui comprend aujourd'hui 55 445 points de code sur 65 536. BPM couvre presque toutes les langues humaines dans le monde, y compris les symboles chinois-japonais-coréen (CJK).
Le temps a passé et de nouveaux jeux de caractères asiatiques ont été ajoutés, les symboles chinois ont pris plus de 70 000 points seuls. Maintenant, il y a même des points Emoji dans le cadre de la norme 😺. De nouveaux avions "supplémentaires" ont été ajoutés. La salle UCS-2 n'était pas suffisante pour couvrir quelque chose de plus grand que Plane-0.
Décision Unicode
Créez UTF-16 basé sur UCS-2. Rendre UTF-16 dynamique, donc il prend 2 octets ou 4 octets par point. Attribuez 1 024 points U + D800 – U + DBFF, appelés High Surrogates, à UTF-16; affectez 1024 symboles U + DC00 – U + DFFF, appelés Low Surrogates, à UTF-16.
Avec ces changements, le BPM est couvert avec 1 bloc de 16 bits en UTF-16, tandis que tous les «caractères supplémentaires» sont recouverts de paires de substitution présentant 2 blocs de 16 bits chacun, au total 1024x1024 = 1 048 576 points.
Un substitut élevé précède un substitut faible . Tout écart par rapport à cette règle est considéré comme un mauvais encodage. Par exemple, un substitut sans paire est incorrect, un substitut bas devant un substitut élevé est incorrect.
𝄞, 'MUSICAL SYMBOL G CLEF', est codé en UTF-16 comme une paire de substituts 0xD834 0xDD1E (2 par 2 octets),
en UTF-8 comme 0xF0 0x9D 0x84 0x9E (4 par 1 octet),
en UTF-32 comme 0x0001D11E (1 sur 4 octets).
Situation actuelle
Pour prendre en charge les applications héritées avec des encodages UTF-8 / UTF-16 incorrects, un nouveau WTF-8 standard , Wobbly Transformation Format, a été créé. Il prend en charge les points de substitution arbitraires, tels qu'un substitut non apparié ou une séquence incorrecte. Aujourd'hui, certains produits ne sont pas conformes à la norme et traitent UTF-8 comme WTF-8.
De nombreux détails historiques ont été supprimés pour suivre le sujet ⚖.
La dernière norme Unicode est disponible sur http://www.unicode.org/versions/latest
la source
Une paire de substitution est constituée de deux «unités de code» en UTF-16 qui constituent un «point de code». La documentation Java indique que ces «points de code» seront toujours valides, avec leurs «unités de code» correctement ordonnées, après l'inverse. Il indique en outre que deux unités de code de substitution non appariées peuvent être inversées et former une paire de substitution valide. Ce qui signifie que s'il y a des unités de code non appariées, il y a une chance que l'inverse de l'inverse ne soit pas le même!
Notez cependant que la documentation ne dit rien sur les graphèmes - qui sont plusieurs points de code combinés. Ce qui signifie que e et l'accent qui l'accompagne peuvent encore être commutés, plaçant ainsi l'accent avant le e. Ce qui signifie que s'il y a une autre voyelle avant le e, elle peut avoir l'accent qui était sur le e.
Yikes!
la source