Caractères et octets -...

48
Caractères et octets

Transcript of Caractères et octets -...

Page 1: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Caractères et octets

Page 2: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

bytes

Un nouveau type fondamental, qui ressemble les chaînes str, mais :

● str = séquence de caractères Unicode

● bytes = séquence d'octets

Page 3: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Unicode vs OctetsUne séquence de 6 caractères Unicode:

>>> s = 'aèßβ中文 '

>>> type(s)

<class 'str'>

Une séquence de 3 octets 0xFF, 0x01, 0xAC :

>>> t = b'\xff\x01\xac'

>>> type(t)

<class 'bytes'>

Dans bytes, \xXY où X et Y sont chiffres hexadécimaux, représente l'octet 0xXY.

Page 4: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Unicode● énorme liste de tous les caractères existants au

monde (présent et passé)● définit 1 114 112 code points (sur 32 bits)

Code point Caractère

0x41 = 65 A

0xE8 = 232 è

0xDF = 223 ß

0x4E2D = 20013 中

Page 5: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Séquences d’échappement

Dans bytes :● b'\xX1X2' représente l'octet 0xX1X2.

Dans str :● '\xX1X2'

● '\uX1X2X3X4'

● '\UX1X2X3X4X5X6X7X8'

représentent le caractère Unicode au code point 0xX1X2, 0xX1X2X3X4, 0xX1X2X3X4X5X6X7X8, respectivement.

Page 6: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Encodage de caractères

Les fichier, la mémoire, les connexions réseau etc., sont des séquence d'octets.

Comment convertir du texte en octets ?

Première solution : code ASCII● sur 7 bits (premier bit de l'octet = 0)● 27 = 128 caractères possibles

Les codes entre 0x20 et 0x7E sont les caractères affichable (chiffres, lettres latines, ponctuation, ...)

Page 7: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général
Page 8: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

bytes

Dans les séquences bytes, on peut employer les caractères ASCII.

>>> t = b'a\xffz'

>>> len(t)

3

En fait, si l'un des codes hexadécimaux employés correspond à un caractère ASCII, Python l'affiche automatiquement.

>>> t = b'\x41\x42\xff'

>>> t

b'AB\xff'

Page 9: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Encodage de caractères

On peut aisément encoder du texte anglais avec ASCII, mais que faire pour les autres langues du monde ?

Plusieurs encodages « partiels » ont été proposés au fil des années : ISO-8859-1, ISO-8859-15, Windows-1252, etc. etc. etc.

Solution « universelle » acceptée aujourd'hui :

UTF-8

Recouvre Unicode entièrement.

Page 10: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Encodage de caractères

UTF-8 est un encodage multi-octet à longueur variable.

Chaque caractère Unicode est encodé avec un ou plusieurs octets.

Exemple :

Caractère Unicode Encodage UTF-8

A (0x41) 0x41

è (0xE8) 0xC3 0xA8

ß (0xDF) 0xC3 0x9F

中 (0x4E2D) 0xE4 0xB8 0xAD

Page 11: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Encodage de caractères

Deux méthodes de conversion qui par défaut utilisent l'encodage UTF-8 :

● chaîne (str) →octets (bytes)

>>> 'è'.encode()

b'\xc3\xa8'

● octets (bytes) →chaîne (str)

>>> b'\xc3\xa8'.decode()

'è'

Page 12: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Fichiers et encodage

Page 13: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Avec les fichiers

Ouvrir, lire (ou écrire) des fichiers :

>>> f = open('book.txt', 'r')

>>> s = f.read()

>>> type(s)

<class 'str'>

Page 14: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Avec les fichiers

Les modes 'r', 'w' utilisent implicitement un encodage (normalement UTF-8).

L'encodage utilisé dépend de la plateforme.

Pour le le découvrir :

>>> import locale

>>> locale.getpreferredencoding()

'UTF-8'

Page 15: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Avec les fichiers

On peut aussi ouvrir, lire et écrire les fichiers directement en mode binaire = sans encodage/décodage.

Avec les modes 'rb', 'wb'

>>> f = open('book.txt', 'rb')

>>> s = f.read()

>>> type(s)

<class 'bytes'>

Page 16: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Sérialisation

Page 17: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Sérialisation

Souvent, il y a le besoin de convertir un objet arbitraire en séquence d'octet, pour :● stocker dans un fichier● envoyer sur réseau● communiquer à un autre processus● ...

Cette conversion s'appelle sérialisation.

Page 18: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Sérialisation

En Python, la librairie standard fournit un module très général qui permet la sérialisation et désérialisation d'objets en bytes :

pickle

● objet Python → bytes● bytes → objet Python

L'encodage utilise un format binaire spécifique à Python.

Page 19: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

pickle● pickle.dumps(objet)

convertit objet en une séquence d'octets, et retourne le résultat

>>> s = pickle.dumps([3.14, 'hello'])

>>> s

b'\x80\x03]q\x00(G@\t\x1e\xb8Q\xeb\x85\x1fX\x05\x00\x00\x00helloq\x01e.'

● pickle.loads(s)

convertit une séquence d'octets s en objet et retourne le résultat

>>> obj = pickle.loads(b'\x80\x03]q\x00(G@\t\x1e \xb8Q\xeb\x85\x1fX\x05\x00\x00\x00helloq\x01e.')

>>> obj

[3.14, 'hello']

Page 20: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

pickle

Deux fonctions qui agissent directement sur les fichier :● pickle.dump(objet, fichier)

convertit objet en une séquence d'octets, et écrit le résultat dans fichier

>>> f = open('basedonne', 'wb')

>>> pickle.dump([3.14, 'hello'], f)● pickle.load(fichier)

lit le contenu de fichier, le convertit en objet, et retourne le résultat

>>> f = open('basedonne', 'rb')

>>> obj = pickle.load(f)

>>> obj

[3.14, 'hello']

Page 21: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

pickle

Quels objets sont « pickables » ?

● None, booléens, nombres, chaînes● conteneurs : listes, tuples, dictionnaires (pourvu

que les objets contenus soient « pickables »)● instances des classes

Page 22: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

pickle

On peut utiliser pickle pour stocker les instances des classes, mais pour les récupérer il faut avoir déjà la définition de la classe. Normalement cette définition est disponible dans le programme.

Par exemple, on lance le programme suivant :

class Vecteur:

def __init__(self, x, y):

self.x, self.y = x, y

f = open('db.pickle', 'wb')

pickle.dump(Vecteur(3, 4), f)

f.close()

Page 23: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

pickle

Si après l'exécution du programme précédent, on essaie dans la console :

>>> f = open('db.pickle', 'rb')

>>> v = pickle.load(f)

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

AttributeError: Can't get attribute 'Vecteur' on <module '__main__' (built-in)>

Une exception est levée : la classe Vecteur n'est pas définie.

Page 24: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

pickleTrès utile pour créer des simples bases de données, par exemple avec un dictionnaire.

import pickle

def enregistrer_points(p):

f = open('pointsjeu.pickle', 'wb')

pickle.dump(p, f)

f.close()

def lire_points():

f = open('pointsjeu.pickle', 'rb')

p = pickle.load(f)

f.close()

return p

points = {'Jean' : 10, 'Yasmine' : 15, 'Geronimo' : 30}

enregistrer_points(points)

points2 = lire_points()

Page 25: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Page 26: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Outil puissant pour la recherche du texte basé sur un pattern (motif).

Comme les « wildcards » de la shell :● « *.txt » →book.txt

log.txtblabla.txt.txtetc.

● « ?at.png »→cat.pngbat.pngfat.pngetc.

...mais beaucoup plus puissant.

Page 27: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Python utilise des regex similaires à ceux de Perl.

● la plus part de caractères dans une regex correspondent identiquement dans le texte:

toto → toto

Toto → Toto

cat → cat● certains caractères (métacaractères) signalent que

des substitutions sont à faire.Les métacaractères :

. ^ $ * + ? { } [ ] \ | ( )

Page 28: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Normalement, la recherche est effectué par ligne.

Dans un texte :

bonjour à tous

hello hello hello world

tous les livres

La regex « tous » trouvera...

Page 29: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Normalement, la recherche est effectué par ligne.

Dans un texte :

bonjour à tous

hello hello hello world

tous les livres

La regex « tous » trouvera...

Page 30: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Répétitions de l'élément qui précède :● * zéro ou plus répétitions● + au moins une répétition● ? zéro ou une répétition● {n,m} entre n et m répétition

ab*c → ac, abc, abbc, abbbc, ...

ab+c → abc, abbc, abbbc, ...

ab?c → ac, abc

ab{3,5}c → abbbc, abbbbc, abbbbbc

Page 31: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Classes de caractèrese avec [ ]

[abc]bla → abla, bbla, cbla

On peut peut utiliser des intervalles Unicode avec le « tiret » :

[a-z]bla → abla, bbla, ... zbla

[0-9] →0, 1, 2, ... 9

x[B-F] → xB, xC, xD, xE, xF

[丠 -严 ] → 丠 , 両 , 丢 , 丣 , 两 , 严

Page 32: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Un point « . » correspond à n'importe quel caractère sauf retourne à la ligne

a.b → axb, aùb, a7b, a b, ...

a.*b → a12 21b, axyxyxb, ab, ...

a.?b → ab, axb, aùb, ...

Page 33: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières● ^ début de la ligne● $ fin de la ligne

Dans un texte :

bonjour à tous

hello hello hello world

tous les livres

La regex « ^tous » trouvera...

Page 34: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières● ^ début de la ligne● $ fin de la ligne

Dans un texte :

bonjour à tous

hello hello hello world

tous les livres

La regex « ^tous » trouvera...

Page 35: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières● ^ début de la ligne● $ fin de la ligne

Dans un texte :

bonjour à tous

hello hello hello world

tous les livres

La regex « tous$ » trouvera...

Page 36: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières● ^ début de la ligne● $ fin de la ligne

Dans un texte :

bonjour à tous

hello hello hello world

tous les livres

La regex « tous$ » trouvera...

Page 37: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Un barre vertical « | » : opérateur ou.

Dans un text :

Le chien blanc poursuit le chat noir.

La regex « chien|chat » trouvera...

Page 38: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Un barre vertical « | » : opérateur ou.

Dans un text :

Le chien blanc poursuit le chat noir.

La regex « chien|chat » trouvera...

Page 39: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Parenthèses ( ) pour créer des groupes.

(ab)+ → ab, abab, ababab, ...

(cat|dog)+ →

cat, dog, catcat, catdog, dogcat, ...

Page 40: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

L'antislash introduit ensembles de caractères prédéfinis :

\d chiffre

\D non-chiffre

\w alphanumérique

\W non-alphanumérique

\s blanc

\S non-blanc

\w+\s\w+ → foo bar, a b, c123 1919

Page 41: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

L'antislash permet aussi d'introduire les métacaractères littéralement :

\*\(hello\)\* → *(hello)*

Bonjour \? → Bonjour ?

3\.14 → 3.14

Page 42: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

En Python : module standard re.

La regex est compilée à partir d'une chaîne :

import re

p = re.compile('a.?b')

Avec l'objet qui représente la regex compilée, on peut effectuer des recherches.

Page 43: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Problème : l'antislash est déjà utilisé dans les chaînes Python pour les caractères spéciaux.

Pour éviter une collision, on veut empêcher à Python d'interpréter l'antislash, et le passer littéralement aux fonctions RE.

Ça se fait en préfixant la chaîne avec r :

p = re.compile(r'bonjour \?')

q = re.compile(r'\\o/')

r = re.compile(r'\w+\d\w+')

Page 44: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulièresLes méthodes principales d'un objet regex :

● p.match(s)

Teste si la regex correspond au début de la chaîne s● p.search(s)

Teste si la regex correspond quelque part dans s● p.finditer(s)

Trouve toute le correspondances de la regex et renvoie un itérateur

● p.findall(s)

Trouve toute le correspondances de la regex et renvoie une liste

Page 45: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières.match(), .search() retournent un objet « match », .finditer() retourne un itérateur sur des objets « match »

>>> p = re.compile('a.?b')

>>> m = p.search('balba')

>>> m

<_sre.SRE_Match object; span=(1, 4), match='alb'>

On peut récupérer les infos d'un objet « match » avec :

>>> m.group()

'alb'

>>> m.span()

(1, 4)

Page 46: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières.findall() retourne une liste de chaînes avec toutes les occurences.

>>> p = re.compile(r'\d+')

>>> p.findall('31 octobre, 12 janvier, 4 kilos')

['31', '12', '4']

Page 47: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulières

Il y a des fonctions .match(), .search(), .finditer(), .findall() au niveau du module, pour éviter de compiler la regex :

>>> m = re.search('a.?b', 'balba')

Équivalent à

>>> p = re.compile('a.?b')

>>> m = p.search('balba')

Page 48: Caractères et octets - pageperso.lif.univ-mrs.frpageperso.lif.univ-mrs.fr/~stefano.facchini/python/slides8.pdf · En Python, la librairie standard fournit un module très général

Expressions régulièresParfois, on veut récupérer seulement une partie du pattern.

Ex. dans un texte :

a54b x12x z64x x337x c567c v6w x1x

on veut trouver tous les nombres entre deux x :

x\d+x

Pour sauvegarder une partie du pattern, on peut employer le groupage :

x(\d+)x

Chaque « groupe » est stocké séparément. Les groupes sont récupérable avec la méthode .groups() de l'objet match.

for m in re.finditer(r'x(\d+)x', s):

nombre = m.groups()[0]

print(nombre)