Tout ce que vous n'avez jamais voulu savoir sur la normalisation d'Unicode
Normalisation canonique
Unicode comprend plusieurs façons d'encoder certains caractères, notamment les caractères accentués. La normalisation canonique transforme les points de code en une forme d'encodage canonique. Les points de code qui en résultent devraient apparaître identiques aux points de code originaux, à moins que les polices ou le moteur de rendu ne présentent des bogues.
Quand l'utiliser
Comme les résultats semblent identiques, il est toujours sûr d'appliquer la normalisation canonique à une chaîne de caractères avant de la stocker ou de l'afficher, pour autant que vous puissiez tolérer que le résultat ne soit pas identique, bit par bit, à l'entrée.
La normalisation canonique se présente sous 2 formes : NFD et NFC. Les deux sont équivalentes dans le sens où l'on peut convertir entre ces deux formes sans perte. La comparaison de deux chaînes de caractères sous NFC donnera toujours le même résultat que la comparaison sous NFD.
BDNF
NFD a les personnages complètement développés. C'est la forme de normalisation la plus rapide à calculer, mais elle donne lieu à un plus grand nombre de points de code (c'est-à-dire qu'elle utilise plus d'espace).
Si vous voulez simplement comparer deux chaînes de caractères qui ne sont pas déjà normalisées, c'est la forme de normalisation préférée, sauf si vous savez que vous avez besoin d'une normalisation de compatibilité.
NFC
Le NFC recombine les points de code lorsque cela est possible après avoir exécuté l'algorithme NFD. Cela prend un peu plus de temps, mais donne des chaînes de caractères plus courtes.
Normalisation des compatibilités
Unicode inclut également de nombreux caractères qui n'ont pas lieu d'être, mais qui étaient utilisés dans les jeux de caractères existants. Unicode les a ajoutés pour permettre au texte de ces jeux de caractères d'être traité en Unicode, puis d'être reconverti sans perte.
La normalisation de compatibilité les convertit en la séquence correspondante de caractères "réels", et effectue également une normalisation canonique. Les résultats de la normalisation de compatibilité peuvent ne pas sembler identiques aux originaux.
Les caractères qui contiennent des informations de formatage sont remplacés par ceux qui n'en contiennent pas. Par exemple, le caractère est converti en 9
. D'autres n'impliquent pas de différences de formatage. Par exemple, le caractère numéral romain est converti en lettres normales IX
.
Évidemment, une fois cette transformation effectuée, il n'est plus possible de revenir sans perte au jeu de caractères d'origine.
Quand utiliser
Le Consortium Unicode suggère de penser à la normalisation de la compatibilité comme une ToUpperCase
transformer. C'est quelque chose qui peut être utile dans certaines circonstances, mais il ne faut pas l'appliquer n'importe comment.
Un excellent cas d'utilisation serait celui d'un moteur de recherche, car vous voudriez probablement effectuer une recherche pour 9
pour correspondre .
Une chose que vous ne devriez probablement pas faire est d'afficher le résultat de l'application de la normalisation de la compatibilité à l'utilisateur.
NFKC/NFKD
Le formulaire de normalisation de la compatibilité se présente sous deux formes : NFKD et NFKC. Elles ont la même relation qu'entre NFD et C.
Toute chaîne en NFKC est intrinsèquement aussi en NFC, et il en va de même pour le NFKD et le NFD. Ainsi, NFKD(x)=NFD(NFKC(x))
y NFKC(x)=NFC(NFKD(x))
etc.
Conclusion
En cas de doute, optez pour la normalisation canonique. Choisissez NFC ou NFD en fonction du compromis espace/vitesse applicable, ou en fonction de ce qui est requis par un système avec lequel vous interagissez.
241 votes
Qui sait quelles horreurs se cachent dans le cœur sombre d'un code ?
0 votes
@ObscureRobot Je veux vraiment savoir si ces symboles supplémentaires peuvent avoir des états ou non.
2 votes
@Eonil - Je ne suis pas sûr de ce que signifie "state" dans le contexte de l'unicode.
1 votes
@ObscureRobot Par exemple, un point de code comme celui-ci :
(begin curved line) (char1) (char2) … (charN) (end curved line)
plutôt que ça :(curved line marker prefix) (char1) (curved line marker prefix) (char2) (curved line marker prefix) (char2)
. En d'autres termes, l'unité minimale qui peut être rendue ?3 votes
Cela semble être une bonne question en soi.