Type de caractères, Unicode

\(\newcommand{\ds}{\displaystyle}\) \(\newcommand{\Frac}{\ds\frac}\) \(\renewcommand{\r}{\mathbb{ R}}\) \(\newcommand{\C}{\mathbb{ C}}\) \(\newcommand{\n}{\mathbb{ N}}\) \(\newcommand{\z}{\mathbb{ Z}}\) \(\newcommand{\Q}{\mathbb{ Q}}\) \(\newcommand{\N}{\mathbb{ N}}\) \(\newcommand{\n}{\mathbb{ N}}\) \(\newcommand{\ol}{\overline}\) \(\newcommand{\abs}[1]{\left| \,{#1} \right|}\) \(\newcommand{\pv}{\;;\;}\) \(\newcommand{\ens}[1]{\left\{ {#1} \right\}}\) \(\newcommand{\mens}[1]{\setminus\left\{ {#1} \right\}}\) \(\newcommand{\Par}[1]{\left({#1}\right)}\) \(\newcommand{\pe}[1]{\left\lfloor {#1} \right\rfloor}\) \(\newcommand{\trans}[1]{\,^t\!{#1}}\)

Type de caractères, Unicode

Accéder à certaines familles de caractères

Le module standard string (écrire le nom au singulier) donne accès à certaines listes de caractères. Voici quelques familles remarquables de caractères (les majuscules, les minuscules, etc) et qui sont accessibles avec ce module :

import string

# les caractères minuscules
minus = string.ascii_lowercase
print(minus)
print()

# les caractères majuscules
maj = string.ascii_uppercase
print(maj)
print()

# les chiffres décimaux
chiffres = string.digits
print(chiffres)
print()

# la ponctuation
punct = string.punctuation
print(punct)
print()

# les chiffres hexadécimaux
hexa = string.hexdigits
print(hexa)
print()
abcdefghijklmnopqrstuvwxyz

ABCDEFGHIJKLMNOPQRSTUVWXYZ

0123456789

!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

0123456789abcdefABCDEF

Les listes précédentes peuvent servir en de nombreuses occasions, d’apprentissage en particulier. L’intérêt que présente ici le module string est de dispenser l’utilisateur de la tâche ingrate de saisir sans erreur les listes ci-dessus.

La méthode isspace

On appelle caractères blancs (blank en anglais) les caractères invisibles qui peuvent être présents dans du texte ; il s’agit essentiellement des caractères suivants :

  • l’espace,
  • le saut de ligne
  • la tabulation horizontale
  • la tabulation verticale (rare)

La méthode isspace sert à tester si une chaîne est formée uniquement de caractères « blancs » (noter qu’il y a deux s dans le nom de la méthode). Par exemple, c’est le cas de la chaîne littérale ci-dessous :

1
s = "\n  \t\n  "

Voici un exemple de tests :

1
2
3
4
5
6
7
8
s = "\n  \t\n  "
print(s.isspace())

s = "\n  \t 0 \n  "
print(s.isspace())

s= ''
print(s.isspace())
 9
10
11
True
False
False

On notera (lignes 11 et 15) qu’une chaîne vide n’est pas considérée comme une chaîne formée de blancs.

Changer la casse d’une chaîne

On dispose d’une chaîne s et on veut créer une nouvelle chaîne formée des mêmes caractères mais tous écrits en majuscules, par exemple orange deviendrait ORANGE. Python dispose de la méthode de chaîne upper permettant de changer les caractères en majuscules :

1
2
3
4
5
6
s = "orange"
t = s.upper()

print(s)
print(t)
print(s)
7
8
9
orange
ORANGE
orange
  • Ligne 2 : une chaîne ayant les mêmes caractères que ceux de s, mais en majuscule, est créée.
  • Ligne 6 : La chaîne s est préservée par cette opération (c’était forcé, les chaînes sont immuables). La chaîne t est une deuxième chaîne.

Après application de la méthode upper sur une chaîne s, les caractères suivants figurant dans s restent inchangés :

  • un caractère déjà en majuscule
  • un caractère dépourvu de majuscule

Ainsi :

s = "42 Oranges !"
t = s.upper()
print(s)
print(t)
42 Oranges !
42 ORANGES !

De même, si s est une chaîne, s.lower() renvoie la chaîne ayant mêmes caractères que ceux de s mais en minuscule :

s = "to MARS in 2040"
t = s.lower()
print(s)
print(t)
to MARS in 2040
to mars in 2040

La méthode capitalize et title

Voici un exemple d’action de la méthode capitalize :

s = """le langage Python
créé par GuiDo"""
print(s)
print("-----------")
print(s.capitalize())
le langage Python
créé par GuiDo
-----------
Le langage python
créé par guido

La méthode capitalize appliquée à une chaine « change »

  • en lettre majuscule le premier caractère de la chaîne si ce caractère est une lettre minuscule,
  • en lettre miniscule toutes les majuscules suivantes.

Le changement en lettre majuscule ne s’applique qu’à la première lettre et non pas à chaque début de ligne.

La méthode title est une méthode qui change

  • en lettre majuscule le début de chaque mot d’une chaîne
  • en lettre minuscule toute lettre majuscule qui n’est pas une lettre initiale d’un mot de la chaîne.

Par exemple :

s = """le langage Python
créé par GuiDo"""
print(s)
print("-----------")
print(s.title())
le langage Python
créé par GuiDo
-----------
Le Langage Python
Créé Par Guido

Centrer du texte

La méthode center appliquée à une chaîne permet de centrer cette chaîne en l’entourant de caractères donnés dans un bloc de longueur donnée. Par exemple

s="bonjour".center(20, ".")
print(s)
......bonjour.......

Pour que le texte soit entouré d’espaces, ne pas donner de 2e argument :

s="bonjour".center(20)
print(s)
bonjour

Cette méthode permet de construire facilement le motif suivant :

         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************
         #
         #

Le code est :

n=10
print('\n'.join([("*"*(2*i+1)).center(2*n)for i in range(n)]))
print("#".center(2*n))
print("#".center(2*n))

Les méthodes maketrans et translate

La méthode de chaîne translate permet de transformer une chaîne en une autre par la conversion individuelle de certains de ses caractères. Par exemple, soit à transformer un texte en remplaçant

  • la lettre a par la lettre X
  • la lettre b par la lettre Y
  • la lettre c par la chaîne XY

Ainsi, la chaîne bacdaacbdc sera convertie en YXXYdXXXYYdXY. Voici comment on réalise cette traduction avec la méthode translate :

1
2
3
4
5
6
7
between = {ord("a"):"X", ord("b"):"Y", ord("c"):"XY"}

s="bacdaacbdc"
print(s)
t=s.translate(between)
print(t)
print(s)
 8
 9
10
bacdaacbdc
YXXYdXXXYYdXY
bacdaacbdc
  • Lignes 3 et 8 : la chaîne à convertir
  • Lignes 5 et 9 : la conversion
  • Ligne 10 : la chaîne initiale, bien sûr, n’est pas modifiée
  • Ligne 1 : la table de conversion qui est un dictionnaire dont chaque clé est la valeur unicode du caractère à transformer ; la valeur d’un caractère unicode c s’obtient par ord(c).
  • Ligne 5 : la table de conversion est transmise en argument à la méthode translate

Attention, écrire le dictionnaire sous la forme suivante :

between = {"a":"X", "b":"Y", "c":"XY"}

bien que n’entraînant aucune erreur d’exécution, ne donne pas le résultat attendu (translate renverra la chaîne s telle quelle, sans modification).

Si la valeur associée à une clé k du dictionnaire est :

  • None alors le caractère correspondant à k sera écrasé (éliminé)
  • un entier n alors le caractère correspondant à k sera remplacé par le caractère dont le code unicode est n, autrement dit le caractère chr(n)chr est une fonction standard Python.

Une clé du dictionnaire peut aussi être un code unicode valide, disons k. Ce code correspond au caractère chr(k). Ainsi :

  • si k = 42 alors le caractère correpondant est *
  • si k = 100 alors le caractère correpondant est d

Illustration de ces différentes possibilités :

1
2
3
4
5
6
between = {ord("a"):"X", ord("b"):"Y", ord("c"):42, 100: None}

s="bacdaacbdc"
print(s)
t=s.translate(between)
print(t)
7
8
bacdaacbdc
YX*XX*Y*
  • Lignes 1 et 8 :

    • le caractère c sera remplacé par le symbole * dont le code unicode est 42 ;
    • le caractère d (qui a pour code unicode 100) sera écrasé puisque la valeur de la clé est None.

Plus généralement, si s est une chaîne et si between est une table de conversion de caractères vers des chaînes, alors s.translate(between) crée une chaîne où chaque caractère de s présent dans la table est remplacé dans la chaîne par sa valeur dans la table. La table de conversion n’est pas clairement définie par la documentation Python. En pratique, la table semble se présenter sous deux formes :

  • un dictionnaire dont les clés sont comme il est expliqué ci-dessus ;
  • une table obtenue par la méthode de chaîne maketrans, détaillé ci-dessous.

Création d’une table de conversion avec maketrans

La fonctionnalité essentielle de maketrans est de renvoyer une « table de conversion » utilisable par la méthode translate. L’exemple qui suit montre un exemple typique d’utilisation de cette méthode. Imaginons que l’on veuille créer une table de conversion de caractères où

  • la lettre a est convertie en la lettre X
  • la lettre b est convertie en la lettre Y
  • la lettre c est convertie en la lettre Z

Voici comment maketrans réalise cette table :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
source = 'abc'
cible = 'XYZ'

trans = str.maketrans(source, cible)
print(trans)

s="baebcdfa"
t=s.translate(trans)
print(s)
print(t)
11
12
13
{97: 88, 98: 89, 99: 90}
baebcdfa
YXeYZdfX
  • Lignes 1-2 : on définit deux séquences de caractères de même longueur. La séquence source contient les caractères qui seront remplacés. La séquence cible contient les caractères de remplacement. Les caractères se correspondent positionnellement.
  • Lignes 4 et 11 : maketrans renvoie un dictionnaire qui met en correspondance les caractères des deux séquences données en arguments. Les clés du dictionnaire (ligne 11) sont les valeurs unicodes des caractères de la 1re séquence et les valeurs des clés sont les valeurs unicodes des caractères de remplacement.
  • Ligne 8 : ce dictionnaire est alors utilisable par la méthode translate.
  • Ligne 8 : l’usage est de faire un appel à la méthode maketrans sous la forme str.maketrans puis en donnant en argument les deux séquences de caractères. Pour information, la méthode maketrans est une méthode statique : on peut l’appeler comme méthode de n’importe quelle chaîne, le résultat sera toujours le même et elle ne reçoit pas la chaîne d’où on l’applique comme premier argument (ce qui le cas des méthodes d’instance qui reçoivent self).

Dans l’usage précédent, maketrans peut recevoir un 3e argument z qui est une séquence de caractères. Ces caractères deviendront clés du dictionnaire renvoyé trans et auront pour valeur None dans le dictionnaire, ce qui signifie que l’appel s.translate(trans) écrasera tous les caractères de s figurant dans z. Voici un exemple basé sur le précédent où, en plus, les lettres d et e sont écrasées :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
source = 'abc'
cible = 'XYZ'
perdus = "de"

trans = str.maketrans(source, cible, perdus)
print(trans)

s="baebcdfa"
t=s.translate(trans)
print(s)
print(t)
12
13
14
{97: 88, 98: 89, 99: 90, 100: None, 101: None}
baebcdfa
YXYZfX
  • lignes 3, 5 et 12 : les entiers 100 et 101 sont les valeurs unicodes des caractères d et e et dans le dictionnaire trans, leurs valeurs sont None.
  • lignes 13 et 14 : observer que les lettres d et e ont disparu.

Identificateurs unicodes

Par défaut, l’interpréteur Python suppose que le code source est écrit dans l’encodage UFT-8. Un identificateur de variable ou de fonction présent dans le code-source peut utiliser des caractères UTF-8 autres que les caractères alphanumériques ASCII :

R = 10
π = 3.14

périmètre = 2 * π * R
print(périmètre)
62.800000000000004

Dans le code ci-dessus, les identificateurs π et périmètre utilisent des caractères autres que des caractères alphanumériques ASCII. Toutefois, ce sont des caractères Unicode de la catégorie lettre. En effet, un caractère d’un identificateur autre qu’un chiffre ou le caractère _ doit être de la catégorie lettre, ce qui n’est pas le cas par exemple du symbole monétaire de l’euro :

€ = 1.2
print(€)
  File "invalid_identif_unicode.py", line 1
    € = 1.2
      ^
SyntaxError: invalid character in identifier

Les fonctions chr et ord de conversion unicode

Deux fonctions built-in, chr et ord, permettent de passer d’un caractère à son code Unicode :

  • un appel chr(n) renvoie le caractère ayant l’entier n pour cod e Unicode
  • un appel ord(c) renvoie le code Unicode d’un caractère unicode c donné.

Voici quelques exemples restreints au code ASCII :

print(chr(81))
print(chr(42))
print(ord('*'))
Q
*
42

et des exemples hors du code ASCII :

print(ord("€"))
print(chr(8364))
8364
€

Parcours de tous les caractères unicodes

Les valeurs décimales \(\mathtt{c}\) des codes unicodes vérifient \(\mathtt{0\leq c < 1114112}\). Il est donc possible, à l’aide d’un programme Python, de rechercher exhaustivement des propriétés des différents caractères en parcourant la totalité des caractères possibles. Par exemple, le programme ci-dessous teste le nombre de caractères unicodes reconnus comme des chiffres décimaux :

cpt=0

for i in range(1_114_112):
    c=chr(i)
    if c.isdecimal():
        cpt += 1
print(cpt)
580

Comparaison alphabétique de chaînes unicodes

La comparaison alphabétique par défaut est purement informatique, elle ne tient compte que de l’ordre des codes des caractères Unicodes. Mais l’ordre alphabétique linguistique est différent et possède des règles spécifiques à chaque région (du monde) et qui sont gérées en Python, par un module standard de régionalisation appelé locale. Voici les règles spécifiques pour le français de France : fr_FR. La fonction strcoll du module locale permet de comparer des chaînes en tenant compte des particularités linguistiques (majuscule, accent, caractères spéciaux). Voici un exemple d’utilisation :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import locale

ma_locale = locale.setlocale(locale.LC_ALL, "")
print(ma_locale, end="\n\n")

def comparer(x, y):
    c = locale.strcoll(x, y)
    if c<0:
        print(x, "<", y)
    elif c>0:
        print(y, "<", x)
    else:
        print(y, "=", x)
    print("-"*15)

print(f"Hors locale: oranger < Oranges : {'Oranges' < 'oranger'}")
print("-"*15)
comparer("Oranges", "oranger")
comparer("orangés", "Orange")
comparer("Orange", "orange")
21
22
23
24
25
26
27
28
29
30
fr_FR.UTF-8

Hors locale: oranger < Oranges : True
---------------
oranger < Oranges
---------------
Orange < orangés
---------------
orange < Orange
---------------
  • Lignes 3-4 et 21 : Tous les usages linguistiques (cf. LC_ALL) du domaine fr_FR (français de France) seront pris en compte.
  • Ligne 16 et 23 : Unicode « pur » considère, par défaut, que Oranges est avant oranger (les majuscules sont classées avant)
  • Ligne 25 : en français, oranger est avant Oranges.
  • Ligne 27 : le module locale sait gérer le placement des accents
  • Ligne 28 : En français, les minuscules viennent avant les majuscules.

Pour trier une liste de chaînes en respectant l’ordre alphabétique défini par la locale, voir Tri de chaînes et particularités linguistiques dont l’exemple est repris ci-dessous :

import locale
locale.setlocale(locale.LC_ALL, "")

L = ["Prune", "prune", "levées", "lève-glaces",
     "lèvent", "leçon", "Lecteur"]

print(sorted(L, key=locale.strxfrm))
['leçon', 'Lecteur', 'levées', 'lève-glaces',
'lèvent', 'prune', 'Prune']

Catégorie d’un caractère unicode

L’ensemble des caractères unicodes est partitionné en une trentaine de catégories telles que

lettre, symbole, nombre, ponctuation

puis en sous-catégories comme

lettre majuscule, symbole monétaire, ponctuation fermeture, ponctuation ouverture, etc

Par exemple, le symbole est dans la catégorie [Symbol, Currency].

La liste des catégories est disponible ICI. Cette liste est uniquement en anglais.

Les catégories ne sont pas liées à une langue spécifique. Par exemple, bien que la lettre α ne soit pas dans l’alphabet latin, elle est dans la même catégorie Letter, Lowercase que, par exemple, la lettre a.

Les catégories sont abrégées avec les initiales ; par exemple, la catégorie Letter, Uppercase est abrégée Lu.

Caractère unicode dans une chaîne littérale

Il est possible d’insérer un ou plusieurs caractères unicode dans une chaîne littérale d’un code-source Python.

Plusieurs techniques d’insertion sont possibles, visibles dans le code ci-dessous :

print("Périmètre = 2 \N{greek small letter pi} R")
print("Périmètre = 2 \u03C0 R")
print("Périmètre = 2 π R")
Périmètre = 2 π R
Périmètre = 2 π R
Périmètre = 2 π R

Noter que dans les deux premiers exemples, on utilise un échappement pour placer le caractère, pas dans le 3e exemple. L’affichage peut dépendre de la nature de la console, en particulier, si l’encodage de la console n’est pas en UTF-8, il se peut que certains caractères ne soient pas lisibles. Ci-dessous, on donne quelques précisions sur les 3 procédés employés.

Caractère unicode défini par son nom

Un caractère unicode possède un nom standard. Ce nom est en anglais, par exemple greek small letter pi pour la lettre grecque π (cf. ligne 1 du code ci-dessus). Il est possible de se référer dans une chaîne littérale à un caractère unicode par son nom normalisé en utilisant la séquence d’échappement

\N{nom_unicode}

nom_unicode désigne le nom standard. Il doit s’agir du nom exact mais la casse du nom n’a pas d’importance, par exemple \N{Greek small letter PI} sera reconnue exactement comme \N{greek small letter pi}.

Caractère unicode défini par son code hexadécimal

Chaque caractère unicode possède un unique encodage UTF-8 sous la forme d’un nombre codé avec 4 chiffres hexadécimaux et qui peut commencer par des zéros. Par exemple, la lettre grecque π possède le code UTF-8 suivant : 03C0.

Il est possible de se référer dans une chaîne littérale à un caractère unicode par son code UTF-8 avec la séquence d’échappement

\u{code_hexa}

code_hexa est une suite de 4 chiffres hexadécimaux. Par exemple, le caractère π est défini par la séquence \u03C0, cf. ligne 2 du code ci-dessus.

En particulier, on peut écrire sous cette forme les caractères ASCII, par exemple, l’astérisque * a pour code ASCII hexadécimal le nombre 2A, ce qui donne en unicode littéral :

ast = "\u002A"

print(ast * 10)
**********

Caractère unicode inséré littéralement

Si l’éditeur de code supporte l’encodage UTF-8, au lieu d’écrire le caractère à l’aide d’une séquence d’échappement, il est possible d’insérer le caractère directement, via un copier-coller du caractère, soit par un code propre à l’éditeur de code soit par insertion du caractère après sélection à la souris dans un panneau (cf. ligne 3 du code ci-dessus).

Le module unicodedata

Les caractères unicodes ont chacun un certain nombres de propriétés comme leur nom ou leur catégorie. Le module unicodedata donne accès à ces propriétés.

Ci-dessous, ne sont décrites que les fonctions du module liées aux propriétés de nom et de catégories.

Propriété de nom

Le module unicodedata permet d’obtenir le nom d’un caractère unicode à partir du caractère lui-même et inversement :

1
2
3
4
5
6
7
8
import unicodedata

euro = "euro sign"
c=unicodedata.lookup(euro)
print(c)

name = unicodedata.name("€")
print(name)
 9
10
€
EURO SIGN
  • Ligne 3 : la fonction lookup(my_name) renvoie une chaîne dont le seul caractère est celui dont le nom standardisé my_name est donné à la fonction lookup.
  • Ligne 7 : la fonction name(my_char) renvoie le nom unicode standardisé du caractère my_char.

Noter que certains caractères n’ont pas de nom, par exemple, certains caractères de contrôle comme le saut de ligne LINE FEED, de code ASCII valant le nombre hexadécimal 0A :

import unicodedata

print(unicodedata.name("\n"))
    print(unicodedata.name("\n"))
ValueError: no such name

Catégorie d’un caractère

Le module unicodedata donne accès à la catégorie avec l’attribut category

import unicodedata

for s in "Aaé\N{greek small letter alpha}+\N{infinity}€":
    print(s, unicodedata.category(s))
A Lu
a Ll
é Ll
α Ll
+ Sm
∞ Sm
€ Sc
  • Le caractère A est catégorisé Lu pour Letter, Uppercase.
  • Le caractère a est catégorisé Ll pour Letter, Lowercase
  • Le caractère + est catégorisé Ll pour Symbol, Math
  • Le symbole Euro est catégorisé Sc pour Symbol, Currency.

Caractères littéraux en octal ou en hexadécimal

Une chaîne littérale peut contenir des caractères unicodes définis par leur code octal (en base 8) ou leur code hexadécimal (en base 16). Voici un exemple :

1
2
3
4
5
s = "symétrie : \616 | E"
p = "2 \x2A 3 = 6"
print(s)
print()
print(p)
6
7
8
symétrie : Ǝ | E

2 * 3 = 6
  • Ligne 1 : un caractère donné sous forme de code octal
  • Ligne 2 : un caractère donné sous forme de code hexadécimal

Les codes octal ou hexadécimal sont des séquences d’échappement donc précédés d’un contre-oblique.

Le code octal

Le code octal peut contenir un, deux ou trois chiffres entre 0 et 7. Un code octal peut donc coder jusqu’à \(8^3=512\) caractères. Par défaut, il semble que ce soit le caractère unicode de même valeur qui soit renvoyé, ce que l’on peut tester en utilisant la fonction standard chr :

print("\616" == chr(0o616))
True

Si une contre-oblique précède une suite de chiffres plus grand que 8, ce n’est pas une erreur et la contre-oblique n’est pas vue comme caractère d’échappement :

print("\81")
\81

Le code hexadécimal

Le code hexadécimal commence par la séquence \x et est suivi d’exactement deux chiffres hexadécimaux. Si le code hexadécimal ne possède qu’un seul chiffre, il faut le faire précéder d’un zéro :

1
print("kiwi\x0Arose")
2
3
kiwi
rose
  • Ligne 1 : la valeur hexadécimale d’un saut de ligne est A, il doit être écrit 0A.

Le code hexadécimal ne peut donc coder que 256 caractères. Les premiers 256 caractères du jeu unicode correspondent à l’encodage latin-1.

Unicode, UTF-8

Ce qui suit n’est qu’une présentation sommaire d’Unicode.

Unicode

Unicode est un standard international permettant d’uniformiser le traitement informatique des caractères de pratiquement toutes les langues du monde. Unicode définit plus de 110000 caractères utilisés dans une centaine de langues naturelles et dans des domaines techniques spécifiques (symboles, caractères phonétiques, hiéroglyphes, etc).

Point de code

Les caractères sont codés par des nombres entiers \(n\) dit « point de code » et qui vérifient \(0\leq n < 1114112\). Ce nombre \(n\) est souvent donné en hexadécimal et précédé du préfixe U+. Par exemple, le symbole euro a pour point de code U+20AC.

Chaque caractère peut être identifié par une appellation normalisée (le nom du caractère), par exemple

GREEK SMALL LETTER PI

désigne π, la lettre grecque pi en minuscule.

On constate que la plage de codage des caractères unicodes est de longueur 1 114 112 et donc est beaucoup plus longue que les 110000 caractères. On a la propriété : \(1114112 = 2^16 \times (16 +1)\) et donc le nombre de caractères unicodes peut s’écrire, en hexadécimal, sous la forme 0x110000, cf. Unicode range.

L’UTF-8

UTF-8 est une norme internationale définissant un encodage informatique des caractères unicodes. UTF-8 signifie Universal Transformation Format 8 bits et indique comment transformer un point de code unicode en une suite de 1 à 4 octets (un octet étant une séquence de 8 bits).

UTF-8 est compatible avec de plus anciens encodages

  • l’ASCII 7 bits
  • l’encodage latin-1 sur 8 bits (courant dans les pays d’Europe occidentale),

autrement dit le code latin-1 (et donc ASCII) d’un caractère a même encodage en UTF-8.

En 2021, l’UTF-8 est utilisé dans presque 97% des sites web. L’UTF-8 est aussi le jeu de caractères par défaut sur Android. Depuis mai 2019, Microsoft recommande que tous les logiciels utilisés sur sa plateforme emploient l’encodage UTF-8.

Point de code et encodage UTF-8

Soit c un caractère unicode. Il ne faut pas confondre

  • le point de code de c qui est l’entier figurant dans son code unicode
  • l’encodage UTF-8 de c qui est une suite d’octets

Par exemple, pour le symbole :

  • point de code : U+20AC
  • encodage UTF-8 : les trois octets 0xE2, 0x82, 0xAC.

La plupart du temps, l’utilisateur (y compris le programmeur) n’a pas besoin d’interférer avec les octets d’encodage UTF-8 et interfère avec le caractère via son point de code. L’algorithme de conversion entre code unicode et suite d’octets est présenté en 7 points dans cet article What is UTF-8?.

Documentation :

  • Le Unicode HOWTO du langage Python
  • Wikipedia : Unicode et UTF-8.
  • Livre Fluent Python de Luciano Ramalho, éditeur O’Reilly : le chapitre 4 traite essentiellement d’Unicode sous Python et en entrant dans les détails. Il existe une traduction française de l’ouvrage.

Caractères ASCII

Les caractères ASCII forment une famille de caractères utilisée en informatique et en programmation depuis les années 1960. Avec la généralisation du standard Unicode, ils ont aujourd’hui un rôle beaucoup plus réduit, surtout que Unicode étend l’ASCII tout en restant compatible.

Voici 8 caractères ASCII :

Z    t    >    .    ^    }    a    $

et voici 8 caractères n’appartenant pas à la famille ASCII :

    é    ç    ß   

Les caractères ASCII représentent :

  • les caractères alphanumériques usuels, majuscules ou minuscules et non accentués,
  • des caractères de ponctuation,
  • des caractères symboles comme $ ou %
  • des caractères non imprimables comme le saut de ligne
  • des caractères de contrôle et qui n’ont pas de signification ni de représentation textuelle particulière.

Les caractères ASCII sont d’origine américaine, l’acronyme signifie American Standard Code for Information Interchange ; et donc les caractères ASCII ne sont jamais des caractères accentués. On n’y trouve pas non plus le symbole euro.

On dit parfois qu’un texte utilisant uniquement des caractères ASCII est du texte pur.

Il existe exactement 128 caractères ASCII. Noter que \(128=2^{7}\) : les caractères ASCII sont codés sur 7 bits.

En informatique, les caractères (alphabétiques, chiffres, signe de ponctuation, etc), quand ils sont utilisés dans un cadre de programmation, sont identifiés par un code entier.

Par exemple, dans le codage ASCII, le caractère P majuscule est codé par l’entier 80. Les caractères ASCII sont codés par les entiers de 0 à 127.

L”encodage est la correspondance entre un jeu de caractères plus ou moins riche et le codage de ces caractères par des entiers. L’ASCII est un encodage parmi d’autres.

Au lieu du terme d”encodage, on trouve le terme jeu de caractères (charset en anglais).

L’encodage ASCII a été très utilisé car établi de longue date (1961), minimal et compatible avec de nombreux systèmes informatiques.

Risque de confusion

Il existe des codages ASCII dit « étendus » et qui ont les deux propriétés suivantes :

  • ils englobent les caractères ASCII habituels avec le même codage
  • ils contiennent des caractères supplémentaires, des caractères accentués par exemple

À cause de la première propriété, on dit que ces codages sont des extensions de l’ASCII. L’encodage Latin-1 et plus spécifiquement l’encodage ISO 8859-15 a longtemps été en usage en Europe occidentale avant l’avènement d’Unicode.

Par ailleurs, il n’existe pas une unique extension du codage ASCII.

Quand on fait référence au codage ASCII, sans précision supplémentaire, on ne fait pas référence à des codages ASCII étendus.

Méthodes isdigit, isdecimal, isnumeric

Les méthodes isdigit et isdecimal permettent de reconnaître respectivement les chiffres et les chiffres décimaux avec des variantes de présentation. Les caractères reconnus par isdecimal forment un sous-ensemble des caractères reconnus par isdigit.

La méthode isnumeric permet de reconnaître des caractères représentant des nombres.

isdecimal

isdecimal reconnaît tous les caractères représentant les chiffres décimaux entre 0 et 9, sous différentes formes et dans différentes cultures. Voici quelques caractères représentant le chiffre 5 et reconnus par la méthode isdecimal :

5 𝟝 𝟧 ௫

Le dernier caractère de la liste représentant le chiffre 5 dans l’alphabet tamoul.

isdigit

C’est une extension de la famille précédente. Elle comprend en plus certaines représentations de chiffres, par exemple sous forme d’exposant ou stylisés. Voici deux exemples :

⁵ ⑤

isnumeric

Les caractères reconnus par isnumeric sont un sur-ensemble des caractères reconnus par isdigit. Parmi les caractères non reconnus par isdigit, on trouve, par exemple, des nombres romains, des fractions, des nombres stylisés ou des nombres représentés dans des civilisations non occidentales ou d’anciennes civilisations. Voici quelques exemples :

㊿ 𐅄 Ⅶ ⅕

Autres méthodes de reconnaissance de caractères

La méthode isspace permet de reconnaître les caractères dits blancs comme l’espace (de code ASCII 0x20) ou le saut de ligne (code ASCII 0x0A) ainsi que des caractères servant à définir des espaces en typographie.

La méthode isalpha permet de reconnaître des caractères alphabétiques, appartennant à des alphabet occidentaux ou non, des alphabets mathématiques, etc. Voici quelques exemple de caractères reconnus par la méthode isalpha :

C c Ç ü 𝛟 β

Les méthodes isupper permet de distinguer des versions minuscule et majuscule de caractères reconnus par isalpha.

La méthode isalnum permet de reconnaître les caractères qui sont soit reconnus par isalpha, soit reconnus par isnumeric.

La méthode isprintable reconnaît les caractères unicodes dits imprimables ; il s’agit de ceux n’appartenant pas aux catégories Other ou Separator de l’encodage Unicode. Le caractère saut de ligne, de code ASCII Ox10 est considéré comme non-imprimable de même que tous les caractères de code ASCII entre 0 et 31. Le caractère espace, de code ASCII 32, est le premier caractère du code ASCII qui soit imprimable.