Python >> Tutoriel Python >  >> Python

Comment convertir une chaîne Unicode en un objet chaîne en Python ?

Ce tutoriel vous montrera comment convertir une chaîne Unicode en une chaîne en Python. Si vous connaissez déjà Unicode, vous pouvez ignorer la section de fond suivante et vous plonger immédiatement dans le problème.

Unicode d'arrière-plan

Un peu sur Unicode de Wikipedia.

Unicode est une norme de codage de caractères qui inclut des caractères de presque toutes les langues écrites du monde. La norme est maintenant répandue sur Internet.

La norme a été proposée en 1991 par l'organisation à but non lucratif "Unicode Consortium" (Unicode Inc). L'utilisation de cette norme permet d'encoder un très grand nombre de caractères issus de systèmes d'écriture différents :dans les documents encodés selon la norme Unicode, hiéroglyphe chinois, symboles mathématiques, lettres de l'alphabet grec, alphabet latin et cyrillique, symboles de musique la notation devient inutile et le changement de pages de code devient inutile.

En Unicode, il existe plusieurs formes de représentation (format de transformation Unicode, UTF) :UTF-8, UTF-16 (UTF-16BE, UTF-16LE) et UTF-32 (UTF-32BE, UTF-32LE). Dans le flux de données, UTF-16, l'octet de poids faible peut être écrit soit avant l'ordre supérieur (UTF-16 little-endian, UTF-16LE) soit après l'ordre supérieur (UTF-16 big-endian, UTF-16BE). De même, il existe deux variantes de la forme de présentation à quatre octets - UTF-32LE et UTF-32BE. Tous sont également appelés encodages.

Microsoft Windows NT et les systèmes basés sur celui-ci utilisent principalement la forme UTF-16LE. Les systèmes d'exploitation de type UNIX GNU/Linux, BSD et Mac OS X adoptent UTF-8 pour les fichiers et UTF-32 ou UTF-8 pour la gestion des caractères en mémoire.

Nous recevons souvent en entrée une chaîne de caractères Unicode, qui n'est pas lisible par un utilisateur ordinaire, mais présente de nombreux avantages par rapport au texte ordinaire, par exemple, elle prend moins d'espace mémoire ou prend moins de temps à traiter et à transférer. En fonction des exigences supplémentaires pour la chaîne Unicode ou en fonction de l'environnement (qu'il s'agisse d'un système d'exploitation ou d'un logiciel), il est nécessaire de déterminer l'encodage qui peut et doit être utilisé.

UTF-8 est maintenant l'encodage dominant sur le Web. UTF-8, par rapport à UTF-16, donne le plus grand gain de compacité pour les textes en latin, puisque les lettres latines, les chiffres et les signes de ponctuation les plus courants sont encodés en UTF-8 par un seul octet, et les codes de ceux-ci les caractères correspondent à leurs codes en ASCII.

UTF-16 est un encodage qui permet d'écrire des caractères Unicode dans les plages U + 0000 … U + D7FF et U + E000 … U + 10FFFF (avec un total de 1112064). De plus, chaque caractère est écrit en un ou deux mots (paire de substitution).

UTF-32 est une manière de représenter Unicode dans laquelle chaque caractère fait exactement 4 octets. Le principal avantage de l'UTF-32 par rapport aux encodages de longueur variable est que les caractères Unicode qu'il contient sont directement indexables, donc trouver un caractère par son numéro de position dans le fichier peut être extrêmement rapide, et obtenir n'importe quel caractère dans la n-ième position est un opération qui prend toujours le même temps. Cela facilite également le remplacement des caractères dans les chaînes UTF-32. En revanche, les encodages à longueur variable nécessitent un accès séquentiel au nième caractère, ce qui peut prendre beaucoup de temps. Le principal inconvénient d'UTF-32 est son utilisation inefficace de l'espace puisque quatre octets sont utilisés pour stocker n'importe quel caractère.

Formulation du problème

Supposons que nous ayons une chaîne Unicode et que nous devions la convertir en chaîne Python.

A = '\u0048\u0065\u006C\u006C\u006F'

Assurons-nous du type de données d'entrée :

>>> type(A)
<class 'str'>

Méthode 1. Chaîne

En Python 3, tout le texte est constitué de chaînes Unicode par défaut, ce qui signifie également que u'<text>' la syntaxe n'est plus utilisée.

La plupart des interpréteurs Python prennent en charge Unicode et lorsque la fonction d'impression est appelée, l'interpréteur convertit la séquence d'entrée des caractères d'échappement Unicode en une chaîne.

print(str(A))
# Hello

Cela n'a aucun sens de vérifier le type de données après avoir appliqué la chaîne méthode.

Méthode 2. Repr()

Le repr() intégré La fonction renvoie une chaîne contenant la représentation formelle imprimable d'un objet.

print(repr(A))
# 'Hello'

Vérifiez le type de données :

print(type(repr(A)))
# <class 'str'>

Méthode 3. Module Unicodedata, fonction normaliser

Le normalize() La fonction du module Unicodedata renvoie la forme normale d'une chaîne Unicode. Les valeurs valides pour le formulaire sont NFC, NFKC, NFD et NFKD.

La norme Unicode définit diverses formes de normalisation de chaînes Unicode basées sur la définition de l'équivalence canonique et de l'équivalence de compatibilité. En Unicode, plusieurs caractères peuvent être exprimés de différentes manières. Par exemple, le caractère U + 00C7 (LETTRE MAJUSCULE LATINE C AVEC CEDILLA) peut également être exprimé comme la séquence U + 0043 (LETTRE MAJUSCULE LATINE C) U + 0327 (COMBINING CEDILLA).

Il existe deux formes normales pour chaque caractère :la forme normale C et la forme normale D. La forme normale D (NFD) est également connue sous le nom de décomposition canonique et traduit chaque caractère en forme décomposée. La forme normale C (NFC) applique d'abord la décomposition canonique, puis recrée les caractères pré-combinés.

En plus de ces deux formes, il existe deux formes normales supplémentaires basées sur l'équivalence de compatibilité. Certains caractères pris en charge dans Unicode sont généralement combinés avec d'autres caractères. Par exemple, U + 2160 (CHIFFRE ROMAIN UN) est bien le même que U + 0049 (LETTRE MAJUSCULE LATINE I). Cependant, il est pris en charge en Unicode pour la compatibilité avec les jeux de caractères existants tels que gb2312.

La forme normale KD (NFKD) appliquera la décomposition de compatibilité, c'est-à-dire remplacera tous les symboles de compatibilité par leurs équivalents. La forme normale KC (NFKC) applique d'abord la décomposition de compatibilité, puis la composition canonique.

Même si deux chaînes Unicode sont normalisées et se ressemblent pour les humains si l'une a des caractères combinés et l'autre non, elles peuvent ne pas correspondre.

import unicodedata 
print(unicodedata.normalize('NFC', A))
# Hello

Vérifions le type de données après normalisation :

print(type(unicodedata.normalize('NFC', A)))
# <class 'str'>

Méthode 4. Compréhension de la liste et str.join

Le str.join() renvoie une chaîne qui est la concaténation (union) de tous les éléments des chaînes de l'itérable.

Dans la dernière ligne, les éléments sont combinés les uns avec les autres à l'aide de la chaîne de séparation str.

S'il y a des valeurs non-chaîne dans la séquence itérable, y compris des octets, l'exception TypeError est déclenchée.

Voyons comment cela fonctionne :

print(''.join([str(i) for i in A]))
# Hello

'' – un caractère de chaîne vide joint les éléments de la liste que nous avons compilée à partir des éléments de la chaîne A en utilisant la méthode join.

Puisque nous avons indiqué d'envelopper chaque itérable de la liste avec la fonction str, nous pouvons supposer en toute sécurité que le résultat sera le type de données souhaité :

print(type(''.join([str(i) for i in A])))
# <class 'str'>

Méthode 5. Bibliothèque ftfy

Le nom complet de cette bibliothèque est Corrige le texte pour vous. Il est conçu pour transformer les mauvaises chaînes Unicode (« guillemets » x9d ou ü) en bonnes chaînes Unicode (« guillemets » ou ü respectivement).

Voyons comment cela fonctionne dans notre exemple :

import ftfy
print(ftfy.fix_text(A))
# Hello

Que fait-il avec le type de données de sortie :

print(type(ftfy.fix_text(A)))
# <class 'str'>

Super, c'est ce qu'il te faut, le principal c'est que la bibliothèque reste accessible;)

Méthode 6. Module io

Le module IO est applicable lorsque vous devez effectuer une opération d'E/S sur des fichiers (par exemple, lire ou écrire des fichiers). Vous pouvez utiliser le read() intégré et write() méthodes pour lire ou écrire un fichier, mais ce module nous donne beaucoup plus d'options de code pour ces opérations, telles que l'écriture ou la lecture à partir d'un tampon.

Dans notre exemple simple, cela ressemblerait à ceci :

print(io.StringIO(A).read())
# Hello

io.StringIO fonctionne avec des données de type chaîne, à la fois en entrée et en sortie. Chaque fois qu'une chaîne d'entrée ou un flux de données se compose d'octets ou de caractères Unicode, l'encodage ou le décodage des données est effectué de manière transparente et la traduction facultative des retours à la ligne spécifiques à l'environnement est prise en compte.

Méthode 7. Formater

Cette méthode semble être la plus puissante et la plus efficace puisqu'elle permet de travailler avec tous les types de données :octets, chaînes, entiers et nombres flottants dans différentes représentations (octal, décimal, hexadécimal dans différents registres) en utilisant la spécification du mini-langage, qui vous permet de spécifier non seulement le type de données, mais également le décalage, l'arrondi, le remplissage avec des caractères à la longueur requise, et vous permet également de travailler avec des dictionnaires et leurs index dans diverses variantes.

Vérifions avec notre exemple :

print(format(A, 's'))
# Hello

Ici, "s" est le type de l'objet formaté - chaîne, utilisé par défaut. Plus de détails sur la spécification et la syntaxe ici.