0% ont trouvé ce document utile (0 vote)
156 vues36 pages

Regex Python

Ce document contient plusieurs fiches sur les expressions régulières en Python. Il présente les concepts fondamentaux des expressions régulières comme les jokers, les classes de caractères, les groupes et les captures. Le document détaille également les méthodes du module re comme search, findall et sub.

Transféré par

P R
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
156 vues36 pages

Regex Python

Ce document contient plusieurs fiches sur les expressions régulières en Python. Il présente les concepts fondamentaux des expressions régulières comme les jokers, les classes de caractères, les groupes et les captures. Le document détaille également les méthodes du module re comme search, findall et sub.

Transféré par

P R
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
Vous êtes sur la page 1/ 36

EXPRESSIONS RGULIRES

Table des matires


fiche 0 : trouver et remplacer dans une chane.......................................................3
introduction......................................................................................................................................3
1. Poser le problme..........................................................................................................3
2. Trouver............................................................................................................................3
2.1. ce que dit la documentation......................................................................................................3
2.2. un exemple...............................................................................................................................4
3. Remplacer.......................................................................................................................4
3.1. ce que dit la documentation......................................................................................................4
3.2. un exemple...............................................................................................................................4
4. Dcouper.........................................................................................................................5
4.1. ce que dit la documentation......................................................................................................5
4.2. exemples..................................................................................................................................5

fiche 1 : le module Python RE....................................................................................7


introduction......................................................................................................................................7
1. Matching et Searching...................................................................................................7
1.1. vocabulaire...............................................................................................................................7
1.2. poser le problme.....................................................................................................................7
1.3. compiler le patron.....................................................................................................................7
1.4. comparer et chercher................................................................................................................8
2. Expression rgulire......................................................................................................9
2.1. remarques sur la section prcdente.......................................................................................9
2.2. les jokers et marqueurs fondamentaux...................................................................................10
2.3. rptitions d'un caractre.......................................................................................................10
2.4. consommation........................................................................................................................11
2.5. gourmandise...........................................................................................................................11
2.5. chappement..........................................................................................................................12
3. Des mthodes recherches multiples.......................................................................12
3.1. la mthode findall().................................................................................................................12
3.2. remplacer : la mthode sub()..................................................................................................14
3.3. la mthode split()....................................................................................................................15

fiche 2 : E.R. les fondamentaux...............................................................................16


introduction....................................................................................................................................16
1. Diversifier les jokers et marqueurs.............................................................................16
1.1. jeux de caractres dfinis ou classes.....................................................................................16
1.2. classes et marqueurs usuels prdfinis..................................................................................16
2. Parenthsage...............................................................................................................17
2.1. analogie mathmatique..........................................................................................................17
2.2. un exemple.............................................................................................................................17

E.R. en Python 3 EXPRESSIONS RGULIRES page 1


3. La double analyse lexicale..........................................................................................18
3.1. deux analyses en pipeline......................................................................................................18
3.2. l'chappement dans les chanes en Python............................................................................18
3.3. l'chappement des expressions rgulires.............................................................................20
4. Donner de l'air aux expressions rgulires...............................................................20
4.1. la saisie multiligne des chanes..............................................................................................21
4.2. le commentaire en ligne..........................................................................................................21
4.3. la directive VERBOSE............................................................................................................22
4.4. jouer sur l'implicite..................................................................................................................23
4.5. l'oprateur de chane r............................................................................................................23
5. Expression avec un ou logique..................................................................................24
5.1. le ou logique...........................................................................................................................24
5.2. un exemple sans parenthsage..............................................................................................24
5.2. exemples avec parenthsage.................................................................................................25
6. Les directives insres dans les expressions...........................................................26

fiche 3 : les groupes..................................................................................................27


introduction....................................................................................................................................27
1. Les groupes..................................................................................................................27
1.1. groupement de sous-expressions rgulires..........................................................................27
1.2. exemples avec search()..........................................................................................................27
1.3. exemples avec findall(). .........................................................................................................28
2. Numroter et nommer les groupes.............................................................................29
2.1. rgle de numrotation.............................................................................................................29
2.2. Nommer les groupes..............................................................................................................30
3. Capturer les groupes et utiliser la capture.................................................................30
3.1. capture des groupes...............................................................................................................30
3.2. exemple d'usage du numro ..................................................................................................31
3.3. usage de la convention de nommage.....................................................................................32
3.4. la fonction de remplacement sub() avec capture....................................................................33

fiche 4 : lookahead et lookbehind............................................................................34


1. Lookahead....................................................................................................................34
1.1. lookahead positif ou ngatif....................................................................................................34
1.2. lookahead postpos................................................................................................................34
1.3. lookahead prpos.................................................................................................................34
2. Lookbehind...................................................................................................................35
2.1. lookbehind positif ou ngatif...................................................................................................35
2.2. lookbehind prpos................................................................................................................35
2.2. lookbehind postpos...............................................................................................................36

E.R. en Python 3 page 2


fiche 0 : trouver et remplacer dans une chane.

introduction.
Avant d'aborder le module des expressions rgulires, on va examiner quelques mthodes relatives
aux chanes de caractres ou qui leur sont apparentes.

1. Poser le problme.
Problme : On dispose d'un texte, c'est dire pour Python d'une chane de caractres ; par ailleurs,
on propose un motif, qui est lui aussi une chane de caractres. Le problme consiste dtecter la
prsence du motif dans le texte, et ventuellement de remplacer ce motif par un autre..
Le texte se prsente sous forme d'une chane de caractres en mmoire vive (variable, chane
littrale) ; on ne se pose pas de problme d'encodage (UNICODE) puisque l'on ne cherche pas
transformer la chane en tableau binaire. Attention cependant, si on dispose d'un fichier de texte, le
problme de l'encodage se pose lors du chargement (voir la fiche sur les fichiers de texte en Python) !
Le motif est une chane sans problme particulier : les sauts de lignes sont cods \n, l'antislash est
cod \\. L'antislash protge les quotes contenues dans la chane. Il n'y a pas d'autre utilisation de
l'antislash.
rappel : un antislash en fin de ligne annule la fin de ligne. Il permet par exemple, d'crire une chane
de caractres un peu longue sur plusieurs lignes physiques.

2. Trouver.
2.1. ce que dit la documentation.

str.find(sub[, start[, end]])


retourne le premier indice de la chane o la sous-chane sub est trouve ; si start et end
sont prciss, le domaine de recherche est la sous-chane forme des caractres dont l'indice
est entre les valeurs de start et de end (la tranche commence avec start et se termine
avant end). La mthode retourne -1 en cas d'chec de la recherche.

str.index(sub[, start[, end]])


comme find(), mais lve une exception ValueError si la sous-chane n'est pas trouve.
Cela permet de programmer les ruptures de squences avec des exceptions.

str.rfind(sub[, start[, end]])


comme find(), mais commence par la fin de la chane.

str.rindex(sub[, start[, end]])


comme rfind() mais lve une exception ValueError si la sous-chane n'est pas trouve.

str.count(sub[, start[, end]])


retourne le nombre d'occurrences de la sous-chane sub dans la tranche [start,end]

E.R. en Python 3 fiche 0 : trouver et remplacer dans une chane. page 3


2.2. un exemple.

#!/usr/bin/python3
# rechercher dans une chane
texte = "Un IDE ou \"environnement de dveloppement\" est un logiciel \
constitu d'outils qui facilitent l'criture et les tests dans un \
langage dfini, voire plusieurs.\
\nCet IDE comporte en gnral un diteur avec coloration syntaxique,\
un systme de gestion de fichiers (sauvegarde/chargement),\
un compilateur, un excuteur de programme, un systme d'aide en ligne,\
des indicateurs de syntaxe etc. \
\nLe plus connu est peut tre clipse."

# premire occurence du motif / numrotation qui commence 0


motif = "IDE"
resultat = texte.find(motif)
print ("premire occurence du motif :", resultat)

# nombre d'occurrences du motif


resultat= texte.count (motif)
print ("nombre d'occurrences du motif :",resultat)

# recherche d'un motif avec problme de casse


motif = "clipse"
resultat = (texte.upper()).find(motif.upper())
print (motif, "est prsent comme",texte[resultat:resultat+len(motif)])

rsultat :

>>>
premire occurrence du motif : 3
nombre d'occurrences du motif : 2
clipse est prsent comme clipse
>>>

3. Remplacer.
3.1. ce que dit la documentation.
str.replace(old, new[, count])
retourne une copie de la chane o toutes les occurrences de la sous-chane old sont
remplaces par la chane new. Si la valeur count est prcise, seules les count premires
occurrences sont remplaces.
3.2. un exemple.

#!/usr/bin/python3
# remplacer dans une chane
texte = "Un IDE ou \"environnement de dveloppement\" est un logiciel \

E.R. en Python 3 fiche 0 : trouver et remplacer dans une chane. page 4


constitu d'outils qui facilitent l'criture et les tests dans un \
langage dfini, voire plusieurs.\
\nCet IDE comporte en gnral un diteur avec coloration syntaxique,\
un systme de gestion de fichiers (sauvegarde/chargement),\
un compilateur, un excuteur de programme, un systme d'aide en ligne,\
des indicateurs de syntaxe etc. \
\nLe plus connu est peut tre clipse."
# remplacement
motif = "\n"
resultat = texte.replace(motif, " ")
print (resultat)

rsultat :

>>>
Un IDE ou "environnement de dveloppement" est un logiciel constitu
d'outils qui facilitent l'criture et les tests dans un langage dfini,
voire plusieurs. Cet IDE comporte en gnral un diteur avec coloration
syntaxique,un systme de gestion de fichiers (sauvegarde/chargement),un
compilateur, un excuteur de programme, un systme d'aide en ligne,des
indicateurs de syntaxe etc. Le plus connu est peut tre clipse.
>>>

4. Dcouper.
4.1. ce que dit la documentation.
str.split([sep[, maxsplit]])
retourne une liste de mots de la chane, en utilisant sep comme dlimiteur. Si maxsplit est
donn, il y a au plus maxsplit coupures (et la liste a au plus maxsplit+1 lments).
En l'absence de sparateur spcifi, ou avec le sparateur None, l'espace est considr
comme sparateur.

str.splitlines([keepends])
retourne une liste des lignes de la chane. En principe, le sparateur de ligne n'est pas gard,
sauf si keepend est pos True.

4.2. exemples.

#!/usr/bin/python3
# couper une chane
texte = "123,,456,"
# split
liste = texte.split (",")
print ("texte :",texte, "\nliste :", liste,"\n\n")

# splitline
texte = "\nABC\nDEF\nGHI"
liste = texte.splitlines()
print ("texte :",texte, "\nliste :", liste,"\n\n")

E.R. en Python 3 fiche 0 : trouver et remplacer dans une chane. page 5


# splitline avec keepend
texte = "\nABC\nDEF\nGHI"
liste = texte.splitlines(True)
print ("texte :",texte, "\nliste :", liste,"\n\n")

rsultats :

>>>
texte : 123,,456,
liste : ['123', '', '456', '']

texte :
ABC
DEF
GHI
liste : ['', 'ABC', 'DEF', 'GHI']

texte :
ABC
DEF
GHI
liste : ['\n', 'ABC\n', 'DEF\n', 'GHI']

>>>

E.R. en Python 3 fiche 0 : trouver et remplacer dans une chane. page 6


fiche 1 : le module Python RE

introduction
Les expressions rgulires en Python 3 peuvent tre abordes l'aide du module re :
import re # module des expressions rgulires
Les fichiers du module re.py, re.pyc, re.pyo, respectivement le fichier source, le fichier
compil, le fichier optimis se trouvent dans le rpertoire des librairies Lib, la racine. Il n'y a donc
aucun problme particulier pour son utilisation. C'est l que la machine Python cherche les modules
(aprs le rpertoire actuel, videmment).
Dans les fiches qui suivent, on utilise l'importation sous la forme import ; il faut donc qualifier
systmatiquement les lments constitutifs du module. En production, il se peut qu'il soit intressant,
pour viter des lourdeurs de code, d'utiliser la forme from... import et de dfinir des alias. C'est
videmment tout fait possible, mais ce n'est pas ici le lieu d'en discuter.

1. Matching et Searching.
1.1. vocabulaire.
Pour la clart de l'expos, nous traduirons le verbe to match par correspondre , et to search
par rechercher et donc matching par correspondance et searching par recherche. Il ne
faut pas chercher de signification "intuitive" ces concepts qui ont dans chacun des langages comme
C, Java ou Python un sens prcis, mais malheureusement pas le mme d'un langage l'autre.
1.2. poser le problme.
Problme : On dispose d'un texte, c'est dire pour Python une chane de caractres ; par ailleurs, on
propose un patron (ou motif), qui est lui aussi une chane de caractres. Le problme consiste
dtecter une sous-chane respectant le patron dans le texte et ventuellement remplacer par une
chane prdfinie la (ou les) sous-chanes(s) trouves. D'autres oprations sont possibles, qui seront
vues en leur temps.
Le texte se prsente sous forme d'une chane de caractres en mmoire vive (variable, chane
littrale) ; on ne se pose pas de problme d'encodage (UNICODE par dfaut en version 3 ; en
versions 2.x, le code est le code local. On peut dfinir la norme de l'encodage par une clause
-code-). Si on dispose d'un fichier de texte, le problme de l'encodage se pose lors du chargement !
Le patron est pour l'instant une chane, avec quelques problmes : comme d'habitude, les sauts de
lignes sont cods \n, l'antislash est cod \\. L'antislash protge les quotes. Mais il doit aussi protger
un certain nombre de caractres usuels comme le point, ^, $, + , ?, * . Cela sera explicit plus
compltement dans les fiches qui suivent.

1.3. compiler le patron.


La syntaxe est la suivante :
cpatron = re.compile(patron, directives)
Le type (classe) de cpatron est : '_sre.SRE_Pattern'
_sre est le module appel dans le module re ; SRE_Pattern est le nom de la classe.

Les directives se prsentent sous forme d'un entier : chaque directive est une puissance de deux,
et le paramtre directives est la somme de directives particulires.

E.R. en Python 3 fiche 1 : le module Python RE page 7


constante abrg valeur signification
IGNORECASE I 2 ignorer la casse ; fonctionne avec les lettres accentues
LOCALE L 4 dfinir comme "lettre" ce que la langue locale dfinit comme tel
dans la variable systme.;
MULTILINE M 8 considrer le texte comme dcompos en lignes
(le caractre \n est le dbut de chaque ligne)
DOTALL S 16 considrer le saut de ligne comme un caractre ordinaire.
UNICODE U 32 obsolte dans Python 3
VERBOSE X 64 permettre d'crire des commentaires dans les patrons.
ASCII A 256 permettre de travailler en ASCII

On peut crire indiffremment re.IGNORECASE+re.MULTILINE ou re.I+re.M


En pratique, dans le dbut du travail, seules les directives IGNORECASE, MULTILINE et DOTALL
sont prendre en compte. On verra plus tard la directive VERBOSE.

1.4. comparer et chercher.


* La syntaxe des fonctions est la suivante :
cpatron.search (texte)
cpatron.match (texte)
* La recherche (search()) consiste parcourir le texte depuis le dbut ; si le patron n'est pas
identifiable dans le texte, la fonction retourne None. Sinon, elle retourne une instance de l'objet
MatchObject, appartenant lui aussi au module _sre.
La comparaison (match()) consiste identifier le dbut du texte au patron. Elle retourne None si
aucune comparaison n'est possible. Sinon elle retourne une instance MatchObject.
* l'objet : MatchObject
Cet objet peut tre interrog par ses mthodes. Pour l'instant, les mthodes start() (premier
caractre reconnu) et stop() (position aprs le dernier caractre reconnu)

#!/usr/bin/python3
import re

texte = "Un IDE ou \"environnement de dveloppement\" est un logiciel \


constitu d'outils qui facilitent l'criture et les tests dans un \
langage dfini, voire plusieurs.\
\nCet IDE comporte en gnral un diteur avec coloration syntaxique,\
un systme de gestion de fichiers (sauvegarde/chargement),\
un compilateur, un excuteur de programme, un systme d'aide en ligne,\
des indicateurs de syntaxe etc. \
\nLe plus connu est peut tre clipse."

# recherche du patron dans le texte ; rsultat affich : 158 165


patron = "Cet IDE"
cpatron = re.compile(patron)
resultat = cpatron.search(texte)

E.R. en Python 3 fiche 1 : le module Python RE page 8


if resultat :
print (resultat.start(), resultat.end())
else:
print (resultat)
# comparaison du patron au texte ; rsultat affich : None
resultat = cpatron.match(texte)
if resultat :
print (resultat.start(), resultat.end())
else :
print (resultat)

# comparaison du patron au texte ; rsultat affich : 0 6


patron = "Un IDE"
cpatron = re.compile (patron)
resultat = cpatron.match(texte)
if resultat :
print (resultat.start(), resultat.end())
else :
print (resultat)

# recherche en ignorant la casse ; rsultat affich : 413 420


patron = "clipse"
cpatron = re.compile (patron, re.IGNORECASE)
resultat = cpatron.search(texte)
if resultat :
print (resultat.start(), resultat.end())
else:
print (resultat)

note. Il existe plusieurs prsentations syntaxiques pour les mthodes comme search(). Dans le
script ci-dessus, search() est une mthode de l'objet SRE_Pattern. Mais Python l'a galement
redfini comme une fonction du module re :
exemple : re.search(patron, texte, re.IGNORECASE))...
Pour la clart de l'expos, on s'en tient une seule syntaxe, celle du script ci-dessus, qui a l'avantage
de ressembler ce qui se fait en java.

2. Expression rgulire.
2.1. remarques sur la section prcdente.
La section qui prcde a pour objectif de spcifier une syntaxe : celle requise par le module re pour
faire des oprations assez semblables celles ralises avec plus de simplicit par les mthodes de
la classe str.
Quel est l'apport du module re pour les oprations de recherche, de comparaison, de substitution, de
dcoupage de chanes ? Lorsque l'on fait une recherche ou une substitution dans un traitement de
texte ou un diteur, la chane recherche doit tre explicite. On peut imposer de ne pas diffrencier
majuscules et minuscules, ou de ne rechercher que des mots entiers ; ces amnagements sont
insuffisants.
note : les diteurs et traitements de texte actuels peuvent travailler diffremment !
On peut souhaiter disposer, pour crire les patrons, de jokers (comme le * ou le ? dans les shells des

E.R. en Python 3 fiche 1 : le module Python RE page 9


systmes d'exploitation) ou de conditions (exemple : trouver les virgules qui sont suivies d'un
caractre alphabtique ; trouver les espaces multiples ; se limiter aux caractres alphanumriques).
Les expressions rgulires sont des chanes comportant des jokers et des lments de description
de chanes de caractres.

2.2. les jokers et marqueurs fondamentaux.

signe signification gnrale signification sous directive

. le point remplace tout caractre sauf le sous DOTALL, le point reprsente tout
saut de ligne (\n). caractre, y compris le saut de ligne.

^ Le chevron (circonflexe) reprsente le sous MULTILINE, reprsente en plus la


dbut de la chane analyse. position aprs le saut de ligne

$ Le dollar reprsente la fin de la chane sous MULTILINE, reprsente en plus la


analyse. position avant le saut de ligne.

exemples d'expressions rgulires :


"azer.tyiop" : cette expression rgulire correspond : azer suivi de n'importe quel
caractre, suivi de tyiop sur une ligne. En mode DOTALL, le caractre peut tre le saut de ligne.
En recherche, azeratyiop, azerAtyiop, azer(tyiop, azer.tyiop satisfont au
modle propos.
"^aze" : le patron "aze" doit tre recherch en dbut de texte uniquement en dbut de texte.
En mode MULTILINE, il est aussi recherch en dbut de chaque ligne.
"tyiop$" : le patron "tyiop" est recherch en fin de texte.
En mode MULTILINE, il est aussi recherch en fin de chaque ligne.
"^$" : recherche d'un texte vide ou en mode MULTILINE d'une ligne vide.

2.3. rptitions d'un caractre.

itrateur interprtation
* zro, une ou plusieurs fois le caractre qui prcde
+ une ou plusieurs fois le caractre qui prcde
? zro ou une fois le caractre qui prcde
{m} exactement m fois le caractre qui prcde
{m,} au moins m fois le caractre qui prcde
{m,n} au moins m fois et au plus n fois le caractre qui prcde

exemples :

exp. reg. chanes reconnues


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

E.R. en Python 3 fiche 1 : le module Python RE page 10


ab?c ac, abc
ab{2,}c abbc, abbbc, abbbbc, ....
ab{2,4}c abbc, abbbc, abbbbc

2.4. consommation.
Lorsqu'une recherche est couronne de succs, la partie de la chane comprise entre le dbut de
celle-ci et la fin de la sous-chane trouve est consomme. Ce qui signifie par exemple que la fonction
findall() commence la recherche partir du caractre suivant le dernier caractre consomm. La
recherche est squentielle et elle ne fait aucun retour en arrire.
2.5. gourmandise.
les itrateurs *, +, ? sont gourmands. C'est--dire que dans une recherche, ils ont un
comportement qui conduit reconnatre la plus grande chane possible. Ils consomment la chane au
maximum, mme si une correspondance a dj t trouve sur le patron propos.
Par exemple, supposons que l'on ait :
texte = "<h1>Expressions Rgulires</h1>"
patron = "<.*>"
Le sous-motif .* conduit avoir le plus grand texte possible : l'expression rgulire s'identifie tout le
texte. Il faut lire patron comme :
le caractre < pour commencer ; un maximum de caractres ; le caractre > pour finir.
On aurait pu souhaiter au contraire une identification <h1>, c'est--dire :
le caractre < pour commencer ; un minimum de caractres ; le caractre >.
Une nouvelle classe d'itrateurs ralisent ces oprations :

itrateur interprtation
*? zro, une ou plusieurs fois le caractre qui prcde ; non gourmand. Dans une
expression, *? s'identifie la plus petite chane possible.
+? une ou plusieurs fois le caractre qui prcde ; non gourmand.
?? zro ou une fois le caractre qui prcde ; non gourmand.
{m,n}? le caractre qui prcde m fois.

exemple :

import re

texte = "<<aaAAabbbccaaannn"

patron = "a{2,3}b?"
cpatron = re.compile(patron, re.I)
res = cpatron.findall(texte)
print ("patron :",patron,"rsultat : ",res)

patron = "a{2,3}?b?"
cpatron = re.compile(patron, re.I)

E.R. en Python 3 fiche 1 : le module Python RE page 11


res = cpatron.findall(texte)
print ("patron :",patron,"rsultat : ",res)

patron = "a{2,3}b??"
cpatron = re.compile(patron, re.I)
res = cpatron.findall(texte)
print ("patron :",patron,"rsultat : ",res)

rsultat :

>>>
patron : a{2,3}b? rsultat : ['aaA', 'Aab', 'aaa']
patron : a{2,3}?b? rsultat : ['aa', 'AA', 'aa']
patron : a{2,3}b?? rsultat : ['aaA', 'Aa', 'aaa']
>>>

Pour bien comprendre, il faut simuler la consommation !!!

2.5. chappement.
Les jokers et les oprateurs sont des caractres courants. Comment, dans une expression rgulire
peut-on distinguer ce caractre en tant que caractre et le mme en tant qu'oprateur ou composant
d'un oprateur ? On utilise le mme systme que Python dans ce cas : pour considrer un caractre
comme se reprsentant lui-mme, il faut l'chapper par un antislash. On aura donc pour le point \.,
pour l'astrisque \*, pour le signe plus \+ et ainsi de suite. Cela peut se compliquer ; un chapitre
spcial sera consacr cette question.

3. Des mthodes recherches multiples.


3.1. la mthode findall().
itration de la recherche.
La mthode search() permet de trouver la premire sous-chane qui correspond l'expression
rgulire donne comme patron. On peut itrer la recherche grce la fonction findall(), qui
retourne tous les lments qui correspondent dans une liste de chanes.
Exemple.
problme : on dispose d'une liste de noms de localits et l'on se propose de rechercher celles dont le
nom de termine par ville. On ne distingue pas les majuscules et les minuscules dans la recherche.

Ablon non
Acqueville oui
Agy non
Aigner-Ville oui / majuscules
Airan non
Amay-sur-Orne non
Amblie non
Amfreville oui
Angervillers non / ville non terminal
Angoville oui

E.R. en Python 3 fiche 1 : le module Python RE page 12


Arganchy non
Argences non
Arroville-les-Bains non / ville non terminal
Asnelles non
Asnires-Surville oui

le source :

#!/usr/bin/python3
import re

texte ="Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmay-sur-Orne\
\nAmblie\nAmfreville\nAngervillers\nAngoville\nArganchy\nArgences\
\nArromanches-les-Bains\nAsnelles\nAsnires-Surville"

patron = ".*ville$"
cpatron = re.compile (patron)
resultat = cpatron.findall(texte)
print (resultat, "\n")

cpatron = re.compile (patron, re.MULTILINE)


resultat = cpatron.findall(texte)
print (resultat, "\n")

cpatron = re.compile (patron, re.MULTILINE+re.IGNORECASE)


resultat = cpatron.findall(texte)
print (resultat, "\n")

".*ville$" : une suite gourmande de caractres, suivie de ville, suivie de la fin de texte.
Les fins de chane ne sont pas incluses. Seule la dernire ligne peut tre prise en compte si on ne
met pas de directives !

rsultats :

>>>
['Asnires-Surville']

['Acqueville', 'Amfreville', 'Angoville', 'Asnires-Surville']

['Acqueville', 'Aigner-Ville', 'Amfreville', 'Angoville', 'Asnires-


Surville']

>>>

E.R. en Python 3 fiche 1 : le module Python RE page 13


3.2. remplacer : la mthode sub().
La syntaxe est la suivante :
cpatron.sub (remplacement, texte, [count])
Retourne le texte avec ses remplacements. La valeur remplacement est une chane (qui peut tre
obtenue par application d'une fonction, appele chaque remplacement). count fixe le nombre
maximum de remplacements ; 0 est la valeur par dfaut et signifie (paradoxalement) que tous les
remplacements possibles doivent tre effectus.
On a aussi la syntaxe :
cpatron.subn (remplacement, texte, count)
Renvoie un tuple comportant la nouvelle chane et le nombre de remplacements.

#!/usr/bin/python3
# substitution dans une chane
import re

texte = "Retourne le texte avec ses remplacements. La \


valeur remplacement est une chane (qui peut tre obtenue \
par application d'une fonction, appele chaque \
remplacement). count donne le maximum de remplacements ; \
0 est la valeur par dfaut et signifie que tous les remplacements\
possibles doivent tre effectus."

patron= "\. " # antislash de protection du point


remplacement ="\n\n"
cpatron = re.compile(patron)
nouveau = cpatron.sub(remplacement, texte)
print (nouveau)
print ("\n************************************\n")

retTuple = cpatron.subn (remplacement, texte)


print (retTuple)

rsultat :

>>>
Retourne le texte avec ses remplacements

La valeur remplacement est une chane (qui peut tre obtenue


par application d'une fonction, appele chaque remplacement)

count donne le maximum de remplacements ; 0 est la valeur par dfaut


et signifie que tous les remplacements possibles doivent tre effectus.

************************************

("Retourne le texte avec ses remplacements\n\nLa valeur remplacement


est une chane (qui peut tre obtenue par application d'une

E.R. en Python 3 fiche 1 : le module Python RE page 14


fonction, appele chaque remplacement)\n\ncount donne le maximum
de remplacements ; 0 est la valeur par dfaut et signifie que tous
les remplacements possibles doivent tre effectus.", 2)
>>>

3.3. la mthode split()


La syntaxe est la suivante :
cpatron.split(texte, [maxsplit])
Pour mmoire, reprenons l'exemple prcdent avec split() au lieu de findall()

>>>
['Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmay-sur-
Orne\nAmblie\nAmfreville\nAngervillers\nAngoville\nArganchy\nArgences\n
Arromanches-les-Bains\nAsnelles\n', '']

['Ablon\n', '\nAgy\nAigner-Ville\nAiran\nAmay-sur-Orne\nAmblie\n',
'\nAngervillers\n', '\nArganchy\nArgences\nArromanches-les-
Bains\nAsnelles\n', '']

['Ablon\n', '\nAgy\n', '\nAiran\nAmay-sur-Orne\nAmblie\n',


'\nAngervillers\n', '\nArganchy\nArgences\nArromanches-les-
Bains\nAsnelles\n', '']

>>>

E.R. en Python 3 fiche 1 : le module Python RE page 15


fiche 2 : E.R. les fondamentaux.

introduction.
Les oprateurs vus dans la fiche qui prcde permettent de rpondre aux problmes lis la
rptition d'un caractre. Le seul joker dont on dispose est le point (sous deux acceptions, avec ou
sans fin de ligne). La premire extension souhaitable est de diversifier les jokers.

1. Diversifier les jokers et marqueurs.


1.1. jeux de caractres dfinis ou classes.
Au lieu de dire "tout caractre" comme avec le joker "point", on peut dfinir en extension un jeu de
caractres. La syntaxe est simple :
[caractres du jeu]
Les caractres sont crits en suivant, dans une suite sans espacements : [abcABC$*+] est le jeu
(la classe) des 9 caractres a,b,c,A,B,C,$,*,+
Il n'est pas utile d'chapper les caractres litigieux des expressions rgulires comme *, +, . etc.
C'est une bonne mthode de protection : on crit [*] au lieu de \*
Il existe une forme abrge pour les squences : premier et dernier caractre spars par un trait
d'union : [a-z] pour une minuscule, [A-Z] pour une majuscule, [0-9] pour un chiffre.
C'est ainsi que [a-zA-Z] quivaut "toute lettre ASCII". Le jeu [-] est tout fait valide.
Une dfinition de jeu peut tre dfinie par exclusion : il suffit de commencer par ^. Par exemple le jeu
[^5] dfinit tout caractre sauf 5. [^0-9] : tout caractre sauf un chiffre.
Pour viter certaines protections lourdes, on peut dfinir des jeux un caractre : [*], ou [+], ou
[\\] ; cela remplace avantageusement \* \+ ou \\\\
note. Le caractre ^ doit tre protg lorsque son utilisation est littrale, soit en dbut d'expression,
soit en dbut de jeu de caractre : [\^abcd]; [\^]. On ne peut pas crire [^].

1.2. classes et marqueurs usuels prdfinis.


Certaines classes sont prdfinies, ainsi que certains marqueurs :

jeu prdfini signification


\A trouver uniquement au dbut de la chane. Ressemble ^ mais n'est pas affect par
la directive MULTILINE.
\b \b est rserv en python (c'est le backspace) ; il faut donc crire \\b pour utiliser
dans une chane Python. Le caractre qui suit est en dbut ou fin de mot.
\B le caractre qui suit n'est ni en dbut de mot, ni en fin de mot.
\d quivalent de [0-9]
\D tout caractre sauf un chiffre
\s quivaut [ \b\t\n\r\f\v], espace, backspace, tabulation, fin de ligne(LF),
dbut de ligne (CR), la ligne (FF), tabulation verticale. On dsigne parfois ces
caractres comme des blancs.
\S tout caractre sauf ceux de \s

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 16


\w quivalent [a-zA-Z0-9_], caractres alphanumriques. Peut tre affect par la
directive LOCALE.
\W tout caractre non alphanumrique
\Z trouve uniquement en fin de la chane. Ressemble $ mais est insensible la
directive MULTILINE.

2. Parenthsage.
2.1. analogie mathmatique.
En calcul numrique, on utilise les parenthses pour hirarchiser les oprations. Il en est de mme
pour les expressions rgulires. On peut parenthser une sous-expression rgulire et lui appliquer
les oprateurs d'itration vus pour les caractres.
ATTENTION !
Le parenthsage a une syntaxe peu intuitive et droutante :
(?:expression rgulire)

2.2. un exemple.
problme : examiner si une chane est une adresse mail valide. Une adresse mail comporte une ou
deux chanes alphanumriques ; dans ce second cas, un point les spare. Le caractre @ suit. La
seconde partie est constitue d'une suite d'au moins deux chanes alphanumriques spares par un
point.

#!/usr/bin/python3
import re
textes1 = ['[email protected]', "[email protected]",
"[email protected]",'zorlubfree.fr']
textes2 = ['zorlub@free', "[email protected]",
"[email protected]. fr","[email protected] "]

g_patron = "^\w+(?:[.]\w+)?" # partie gauche


d_patron = "\w+(?:[.]\w+)+$ "# partie droite
cpatron = re.compile(g_patron+"@"+d_patron)

for x in textes1 + textes2:


res = cpatron.search(x)
if res:
print (x, "est correct")
else:
print (x, "n'est pas une adresse valide")

>>>
[email protected] est correct
[email protected] est correct
[email protected] n'est pas une adresse valide
zorlubfree.fr n'est pas une adresse valide
zorlub@free n'est pas une adresse valide
[email protected] est correct

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 17


[email protected]. fr n'est pas une adresse valide
[email protected] n'est pas une adresse valide
>>>

3. La double analyse lexicale.

Un analyseur lexical prend un flot de caractres sur son entre standard, isole les units lexicales, et
envoie un flot d'units lexicales sur sa sortie standard. Une unit lexicale peut tre un identificateur,
un mot rserv du langage, un signe (+ - * / ! etc), un dlimiteur (parenthse, accolade, crochet, /*,
*/ etc), c'est--dire toute unit pertinente pour l'analyse syntaxique.

3.1. deux analyses en pipeline.


Que se passe-t-il entre la lecture du source d'une expression rgulire et l'dition d'un patron compil
qui est utilis par les mthodes search(), match(), findall(), sub() et split() ?
patron = chane_source
cpatron = compile(patron)
Il y a deux tapes au niveau lexical : l'analyseur de chane Python lit la chane source et la traite : il en
sort une chane interne dans le format de stockage de Python. C'est ce niveau que sont traits les
caractres spciaux comme le backslash (\b) et la fin de ligne (\n).
Puis l'analyseur lexical de la machine d'analyse des expressions rgulires prend le relai et isole les
units lexicales que comprend l'analyseur d'E.R.. Les jokers, les marqueurs, les expressions sont de
telles units lexicales.

On a figur deux lments qui relvent de l'analyse syntaxique (classe, chane).


3.2. l'chappement dans les chanes en Python.
Lorsque Python ralise l'analyse lexicale d'une chane littrale pour en crer la reprsentation interne,
il lit la reprsentation littrale (flot d'entre) de gauche droite pour en dgager les units lexicales,
qui seront ensuite codes comme un caractre (flot de sortie) :
- l'antislash en fin de ligne est ignor (chanes sur plusieurs lignes). Le changement de ligne
qui suit est ignor galement.

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 18


- les units lexicales tiennent en gnral sur un seul caractre ; c'est le cas des caractres
alphanumriques ou des caractres accentus ou de la ponctuation par exemple.
- certaines units ont besoin de deux caractres dans la chane littrale : par exemple la fin de
ligne est note \n, le backspace \b, la tabulation \t. Ces couples correspondent une seule
unit lexicale (un caractre dans la chane interne).
- certaines peuvent tenir sur un ou deux caractres sans poser de difficult : \" et \'. En
effet, les caractres " et ' tant des dlimiteurs, leur chappement par l'antislash permet de
les considrer comme des littraux. Ainsi si on pose :
maChaine ='papa "Nol" s\'est envol'
taChaine = 'papa \"Nol\" s\'est envol'
saChaine ='papa \"Nol" s\'est envol'
print (maChaine==taChaine,maChaine==saChaine)
on peut vrifier que les trois chanes sont similaires.
- la difficult apparat lorsque l'on utilise l'antislash. L'antislash peut s'chapper lui-mme :
c'est sans ambigit ; mme chose pour " et '. Mais qu'en est-il s'il prcde un caractre qui
ne peut tre chapp. Comme par exemple un espace,les caractres c, d, w, ... L'antislash est
alors considr comme littral !
exemple :
print("\c\d\w")
donne : \c\d\w
- enfin, plus dlicat encore certaines squences antislashes introduisent des squences
spcifiques, comme par exemple des squences unicodes ou numriques (cas de \u \U \x
\N)

Voici ce que dit la documentation officielle :

Escape Sequence Meaning


\newline Backslash and newline ignored
\\ Backslash (\)
\' Single quote (')
\" Double quote (")
\a ASCII Bell (BEL)
\b ASCII Backspace (BS)
\f ASCII Formfeed (FF)
\n ASCII Linefeed (LF)
\r ASCII Carriage Return (CR)
\t ASCII Horizontal Tab (TAB)
\v ASCII Vertical Tab (VT)
\ooo Character with octal value ooo
\xhh Character with hex value hh

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 19


Escape sequences only recognized in string literals are:

Escape Sequence Meaning


\N{name} Character named name in the Unicode database
\uxxxx Character with 16-bit hex value xxxx
\Uxxxxxxxx Character with 32-bit hex value xxxxxxxx

quelque cas :
La chane "\123" donne le caractre de code octal 123 en Unicode, soit S (code 64+2x8+3 = 83) :
print (ord("\123"), "123")
La chane "\u00b5" donne le de code 181 :
print (ord("\u00b5"), "\u00b5")
Chaque caractre unicode a un nom (importer le module unicode):
print (ord("\u00b5"), "\u00b5", unicodedata.name("\u00b5"))
donne : 181 MICRO SIGN

D'o la liste des caractres alphanumriques pour lesquelles l'antislash n'est pas un littral

caractres particuliers pour l'chappement


N U u x 0 1 2 3 4 5 6 7 a b f n r v
On insiste bien sur le fait que l'analyse lexicale de Python s'applique tout ce qui se trouve sur le flot
d'entre de l'analyseur, texte comme patron.
3.3. l'chappement des expressions rgulires.
Lors de la compilation, c'est la chane interne de Python qui est examine par l'analyseur lexical du
moteur d'analyse des expressions rgulires. Il y a alors le second niveau d'analyse, qui lui aussi
utilise l'antislash pour caractre d'chappement ! Cela ne pose pas de problme avec ^, ( , ) , {
, }, w, W, B, 8, 9, $. Il y en a un avec les caractres particuliers qu'il faut chapper
l'aide d'un \\ lors de la premire analyse lexicale. Il faut prter une attention particulire aux
caractres b, 0, 1, 2, 3, 4, 5, 6, 7. Quand l'antislash, comme il est doublement caractre
d'chappement, pour l'utiliser comme littral, il vaut mieux l'chapper pour Python, puis pour l'analyse
re, ce qui fait quatre antislash !

4. Donner de l'air aux expressions rgulires.


le problme : les expressions rgulires sont particulirement indigestes. Parmi les faits qui
concourent une lecture difficile on peut citer :
- l'absence de caractres d'aration, ce que l'on appelle parfois "les blancs" : espaces,
tabulation, saut de ligne ;
- l'absence de commentaires explicatifs insrs dans l'expression ;
- les difficults lies au fait que l'on cumule deux niveaux d'analyse : l'analyse lexicale de
Python qui donne une premire reprsentation de l'expression, puis l'analyse lexicale du
moteur d'expressions rgulires. La multiplication des chappements est lie cet aspect de
la question.
Cette difficult de lecture peut tre en partie leve par l'utilisation de techniques appartenant l'un ou
l'autre des analyseurs lexicaux.
note : dans les exemples qui suivent, la signification des expressions rgulires n'a pas tre
examine. Ces exemples illustrent l'aration du patron.

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 20


4.1. la saisie multiligne des chanes
En Python, on peut saisir une chane sur plusieurs lignes physiques ; il suffit de terminer chaque
lment significatif du texte par un antislash suivi d'un passage la ligne. Attention, aprs l'antislash il
ne doit rien y avoir !Il y a alors concatnation des segments de texte l'analyse lexicale.
exemple :

#!/usr/bin/python3
import re

textes = "[email protected],[email protected],[email protected],\
[email protected],[email protected],[email protected]"

patron = "\\b\
\w+\
(?:[.]\w+)?\
@\
\w+\
(?:[.]\w+)*\
[.](?:fr|com)\
\\b"
print (patron,"\n")

cpatron = re.compile(patron)

print (cpatron.findall(textes))
>>>
\b\w+(?:[.]\w+)?@\w+(?:[.]\w+)*[.](?:fr|com)\b

['[email protected]', '[email protected]', '[email protected]']


>>>

4.2. le commentaire en ligne.


La syntaxe est (?# texte )
Le texte est un commentaire ; il est ignor. On doit prendre garde ce que le commentaire en ligne
est un lment de l'expression rgulire ; il ne faut pas introduire d'espaces qui seraient pris comme
des caractres constitutifs de l'expression.

exemple :

#!/usr/bin/python3
import re

textes = "[email protected],[email protected],[email protected],\
[email protected],[email protected],[email protected]"

patron = "\\b(?# dbut de mot)\


\w+(?:[.]\w+)?(?# un ou deux mots spars par un point)\

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 21


@\
\w+(?:[.]\w+)*(?# un, ou plusieurs mots spars par un point)\
[.]\
(?:fr|com)(?# le dernier tant soit fr soit com)\
\\b(?# fin de mot)"
print (patron,"\n")

cpatron = re.compile(patron)

print (cpatron.findall(textes))

donne :

>>
\b(?# d> but de mot)\w+(?:[.]\w+)?(?# un ou deux mots spars par
un point)@\w+(?:[.]\w+)*(?# un, ou plusieurs mots spars
par un point)[.](?:fr|com)(?# le dernier tant soit fr soit com)
\b(?# fin de mot)

['[email protected]', '[email protected]', '[email protected]']


>>>

* On a ici combin les deux mthodes : le gain de lisibilit est rel mais ce n'est pas encore le grand
confort : il manque une aration par des espaces par exemple. D'autre part, la mthode de l'antislash
terminal peut introduire des erreurs peu visibles si on ajoute malencontreusement des blancs.
4.3. la directive VERBOSE.
La directive VERBOSE a comme effet d'occulter tous les blancs (espaces, tabulations, fin de ligne...) de
la chane de saisie. De plus, l'introduction dans une ligne du symbole # a le mme effet qu'en Python :
il supprime la fin de ligne physique partir du dise. Encore faut-il qu'il y ait fin de ligne ! La triple
quote s'impose alors ; la chane dlimite ainsi est prise littralement, avec ses fins de lignes.
On dispose de l'aration souhaite, mais au prix d'une perte des blancs et du dise. Il suffit en gnral
d'utiliser le joker\s pour rsoudre le problme, ou alors de protger le caractre dans une classe ou
avec un antislash.
exemple.

#!/usr/bin/python3
import re

textes = "[email protected],[email protected],[email protected],\
[email protected],[email protected],[email protected]"

patron = """
\\b # dbut de mot)
\w+(?:[.]\w+)? # un ou deux mots spars par un point
@\
\w+(?:[.]\w+)* # un, ou plusieurs mots mots spars par un point
[.]\

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 22


(?:fr|com) # le dernier tant soit fr soit com
\\b # fin de mot
"""
print (patron,"\n")

cpatron = re.compile(patron, re.VERBOSE)

print (cpatron.findall(textes))
>>>

\b # dbut de mot)
\w+(?:[.]\w+)? # un ou deux mots spars par un point
@ \w+(?:[.]\w+)* # un, ou plusieurs mots mots spars par un
point
[.] (?:fr|com) # le dernier tant soit fr soit com
\b # fin de mot

['[email protected]', '[email protected]', '[email protected]']


>>>

4.4. jouer sur l'implicite.

#!/usr/bin/python3
import re

textes = "[email protected], [email protected], [email protected],\


[email protected], [email protected], [email protected]"

cpatron = re.compile(
"\\b" # dbut de mot
"\w+" # suite de caractres alphamriques
"(?:[.]\w+)?" # 0 ou 1 point et suite de caractres alphanumriques
"@" #
"\w+" # suite de caractres alphamriques
"(?:[.]\w+)*" # x point et suite de caractres alphanumriques
"[.](?:fr|com)" # suffixe en fr ou en com
"\\b" # fin de mot
)

print (cpatron.findall(textes))

On joue ici triplement sur l'implicite : dans une parenthse, les nouvelles lignes ne sont pas prises en
compte ; les commentaires sont ignors l'analyse lexicale ; deux chanes littrales juxtaposes sont
concatnes... Cela fonctionne, mais c'est dangereux !
4.5. l'oprateur de chane r.
Il existe un oprateur de chane, r, qui permet de court-circuiter l'analyse lexicale de Python. Il suffit

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 23


alors de fournir comme patron la chane d'entre de l'analyseur du moteur d'valuation des
expressions rgulires. On y gagne quelques antislashes ???

#!/usr/bin/python3
import re

textes = "[email protected],[email protected],[email protected],\
[email protected],[email protected],[email protected]"

patron = r"\b\w+(?:[.]\w+)?@\w+(?:[.]\w+)*[.](?:fr|com)\b"
cpatron = re.compile(patron)

print (cpatron.findall(textes))

5. Expression avec un ou logique.


5.1. le ou logique.
Jusque l, on n'a rencontr que des expressions rgulires "additives" : tout l'ensemble dcrit doit
correspondre une sous-chane pour que la correspondance soit reconnue. On peut avoir besoin de
chercher une correspondance avec l'une ou l'autre de deux expressions rgulires. Dans ce cas, on
les spare par le symbole | (barre verticale, le Alt gr 6 du clavier / valeur ASCII 124). On crit A|B
avec A et B comme expressions rgulires.
Plusieurs questions se posent avec le ou logique :
- les deux conditions peuvent-elles tre satisfaites en mme temps ? Cela n'est pas interdit.
- dans quel ordre se fait l'valuation des expressions rgulires ? De gauche droite.
- lorsque l'valuation de la premire expression est satisfaite, la seconde est-elle teste ? La
rponse est non. Cette absence de gourmandise peut parfois causer des surprises, puisque la
seconde valuation aurait pu apporter une solution plus "complte".
- o s'arrte l'analyse lorsqu'une correspondance est dtecte ? l'analyse s'arrte sur le
premier caractre non reconnu (ou la fin de chane).
- peut-on avoir cet oprateur en srie (succession de ou logiques) ou en cascade (insertion
d'une expression avec un ou plusieurs ou dans une expression complexe. La rponse est oui.
Dans la srie, la rgle "de gauche droite" s'applique.
note. le caractre | doit tre protg \| ou constituer un jeu de caractre [|] s'il est littral

5.2. un exemple sans parenthsage.


problme : On dispose d'un texte comportant des noms de communes. On veut en extraire la liste
des noms qui comportent le mot ville (ou Ville) en tant que chane terminale, c'est--dire suivi par un
trait d'union ou en fin de nom. Par exemple Villers n'est pas admis ; mais Maville, Pont-Ville,
Hauteville-Cajun, Ville-Sur-Cher le sont.

#!/usr/bin/python3
import re

texte ="Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmaville-sur-Ville\
\nAmblie\nTrouville\nAngervillers\nAngoville\nArganchy\
\nAsnelles\nAsnires-Surville\nVille\nVilleneuve"

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 24


patron = "^.*ville-.*|^.*ville$"
cpatron = re.compile (patron,re.MULTILINE+re.IGNORECASE)
resultat = cpatron.findall(texte)
print (resultat)
['Acqueville', 'Aigner-Ville', 'Amaville-sur-Ville', 'Trouville',
'Angoville', 'Asnires-Surville', 'Ville']
* attention : le point ne peut tre un \n. En faisant .* on s'arrte automatiquement en fin de ligne si
on l'atteint. Par contre dans la seconde partie de l'alternative, le $ est ncessaire.
* dans le cas de Amaville-sur-Ville, seule la premire expression est value.

5.2. exemples avec parenthsage.


exemple 1.
Rechercher dans une liste Python des adresses mail correctes qui ont pour extension terminale .fr
ou .com ; sont donc rejetes les adresses incorrectes et celles qui n'ont pas la bonne extension.

#!/usr/bin/python3
import re

textes = ["[email protected]","[email protected]","[email protected]",
"[email protected]", "[email protected]" ]

patron = "^\w+(?:[.]\w+)?@\w+(?:[.]\w+)*[.](?:fr|com)$"
cpatron = re.compile(patron)

for x in textes:
res = cpatron.search(x)
if res:
print (x)
>>>
[email protected]
[email protected]
[email protected]
>>>

exemple 2 : mme chose avec findall()

#!/usr/bin/python3
import re

textes = "[email protected],[email protected],[email protected],\
[email protected],[email protected]"

patron = "\\b\w+(?:[.]\w+)?@\w+(?:[.]\w+)*[.](?:fr|com)\\b"
cpatron = re.compile(patron)

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 25


print (cpatron.findall(textes))
>>>
['[email protected]', '[email protected]', '[email protected]']
>>>

6. Les directives insres dans les expressions


On peut insrer les directives dans le patron. La syntaxe est la suivante :
(?iLmsuxa)
o une ou plusieurs lettres peuvent tre absentes : i pour IGNORECASE, L pour LOCALE, m pour
MULTILINE, s pour DOTALL, u pour UNICODE, x pour VERBOSE, a pour ASCII.
tant donn le processus que nous avons recommand, l'usage en est rare ; il n'en est pas de mme
si on avait choisi une autre mthodologie, par exemple celle des fonctions du module re (fonction
re.search(), re.findall() etc).

E.R. en Python 3 fiche 2 : E.R. les fondamentaux. page 26


fiche 3 : les groupes

introduction.
On a dj rencontr un mode de groupement : le "parenthsage" ; il existe un second systme appel
groupe, qui a, en plus des proprits du parenthsage, des proprits trs spcifiques. On prendra
garde que le "groupe" n'est pas l'quivalent du parenthsage mathmatique.

1. Les groupes.
1.1. groupement de sous-expressions rgulires.
Un patron est un groupe ; c'est le groupe de niveau le plus bas, le niveau 0. Si on veut dfinir des
sous-groupes, il suffit de parenthser des sous-expressions rgulires constituant l'expression
globale. Les groupes sont numrots : 0 pour le patron, 1, 2,... pour les sous-groupes. La
numrotation se fait de gauche droite, et pour un groupe, elle est gale au nombre total de
parenthses ouvrantes qui le prcde.
On rcupre les groupes en analysant l'objet SRE_Pattern retourn par search() ; quant la
mthode findall() elle retourne une liste groupes ou de tuples (n-uplets) de groupes (voir
exemple ci-dessous).
note. Les littraux ( et ) doivent tre protgs. Mais attention ! Le point d'interrogation ne peut
suivre la parenthse ouvrante ; il faut aussi le protger : (? se code \(\?.
Les oprateurs comme *, +, ?, |, qui s'appliquent un caractre ou une expression paranthse
s'appliquent un groupe.
1.2. exemples avec search().
exemple 1.

#!/usr/bin/python3
import re
texte ="Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmay-sur-Orne\
\nAmblie\nAmfreville\nAngervillers\nAngoville\nArganchy\nArgences\
\nArromanches-les-Bains\nAsnelles\nAsnires-Surville"

patron = "(.*)ville$"
cpatron = re.compile (patron,re.MULTILINE)
resultat = cpatron.search(texte)
print (resultat.start(0),resultat.end(0), resultat.group(0))
print (resultat.start(1),resultat.end(1), resultat.group(1))

>>>
6 16 Acqueville
6 11 Acque
>>>

exemple 2.

#!/usr/bin/python3
import re
texte ="Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmay-sur-Orne\
\nAmblie\nAmfreville\nAngervillers\nAngoville\nArganchy\nArgences\

E.R. en Python 3 fiche 3 : les groupes page 27


\nArromanches-les-Bains\nAsnelles\nAsnires-Surville"

patron = "(.*)(vi\w*)$"
cpatron = re.compile (patron,re.MULTILINE)
resultat = cpatron.search(texte)
print (resultat.start(0),resultat.end(0), resultat.group(0))
print (resultat.start(1),resultat.end(1), resultat.group(1))
print (resultat.start(2),resultat.end(2), resultat.group(2))
>>>
6 16 Acqueville
6 11 Acque
11 16 ville
>>>

1.3. exemples avec findall().


findall() ne reprend pas ce qu'on a trouv avec le patron, mais ses sous-groupes.

exemple 1.
#!/usr/bin/python3
import re
texte ="Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmay-sur-Orne\
\nAmblie\nAmfreville\nAngervillers\nAngoville\nArganchy\nArgences\
\nArromanches-les-Bains\nAsnelles\nAsnires-Surville"

patron = "(.*)vi\w*$"
cpatron = re.compile (patron, re.MULTILINE)
resultat = cpatron.findall(texte)
print (resultat)
>>>
['Acque', 'Amfre', 'Anger', 'Ango', 'Asnires-Sur']
>>>

exemple 2, avec deux sous-groupes.


#!/usr/bin/python3
import re
texte ="Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmay-sur-Orne\
\nAmblie\nAmfreville\nAngervillers\nAngoville\nArganchy\nArgences\
\nArromanches-les-Bains\nAsnelles\nAsnires-Surville"

patron = "(.*)(vi\w*)$"
cpatron = re.compile (patron, re.MULTILINE+re.IGNORECASE)
resultat = cpatron.findall(texte)
print (resultat)
>>>
[('Acque', 'ville'), ('Aigner-', 'Ville'), ('Amfre', 'ville'),
('Anger', 'villers'), ('Ango', 'ville'), ('Asnires-Sur', 'ville')]
>>>

E.R. en Python 3 fiche 3 : les groupes page 28


exemple 3
On reprend l'exemple prcdent, mais en transformant chaque alternative en groupe. La mthode
findall() continue donner l'valuation des deux groupes. Cependant, si c'est le premier groupe
qui est reconnu, le second n'est pas valu (absence de gourmandise) : il est vide ; si c'est le second
qui est reconnu, le premier est vide parce que non reconnu.

#!/usr/bin/python3
import re

texte ="Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmaville-sur-Ville\
\nAmblie\nTrouville\nAngervillers\nAngoville\nArganchy\
\nAsnelles\nAsnires-Surville\nVille\nVilleneuve"

patron = "(^.*ville-.*)|(^.*ville$)"
cpatron = re.compile (patron,re.MULTILINE+re.IGNORECASE)
resultat = cpatron.findall(texte)
print (resultat)
>>>
[('', 'Acqueville'), ('', 'Aigner-Ville'), ('Amaville-sur-Ville', ''),
('', 'Trouville'), ('', 'Angoville'), ('', 'Asnires-Surville'), ('',
'Ville')]
>>>

2. Numroter et nommer les groupes.


2.1. rgle de numrotation.
rappel : La numrotation se fait de gauche droite, et pour un groupe, elle est gale au nombre total
de parenthses ouvrantes qui le prcde.

#!/usr/bin/python3
import re
texte = " abcdefghijklmnopqrstuvwxyz "

patron = "abc(def(ghi)(jkl))(mno)pqr"
cpatron = re.compile(patron)

res = cpatron.search(texte)
if res :
try:
for i in range (99) : # maximum de 99 groupes
print ("groupe", i , ":", res.group(i))
except:
pass

E.R. en Python 3 fiche 3 : les groupes page 29


donne :

>>>
groupe 0 : abcdefghijklmnopqr
groupe 1 : defghijkl
groupe 2 : ghi
groupe 3 : jkl
groupe 4 : mno
>>>

attention : Si le patron comporte un ou logique la rgle de nmrotage continue s'appliquer. Par


exemple, le patron "ab(c)d|xy(z)" comporte deux groupes : numrots 1 (c) et 2 (z).
2.2. Nommer les groupes.
Il est possible de donner un nom un groupe au moment o on le dfinit. Le nom doit tre un
identificateur Python valide. Il n'y a aucune interfrence avec la numrotation.
La syntaxe est
(?P<nom du groupe>expression rgulire)
exemple :

#!/usr/bin/python3
import re
texte = " abcdefghijklmnopqrstuvwxyz "

patron = "abc(?P<gr1>def(?P<gr2>ghi)(?P<gr3>jkl))(?P<gr4>mno)pqr"
cpatron = re.compile(patron)

res = cpatron.search(texte)
if res :
for i in range (1, 99) :
try :
print ("groupe "+str(i), res.group("gr"+str(i)))
except :
pass

donne :

>>>
groupe 1 defghijkl
groupe 2 ghi
groupe 3 jkl
groupe 4 mno
>>>

3. Capturer les groupes et utiliser la capture.


3.1. capture des groupes.
Lorsqu'un groupe est identifi un segment de chane, la valeur de la sous-chane identifie peut tre

E.R. en Python 3 fiche 3 : les groupes page 30


"capture", et utilise dans l'expression rgulire et dans la fonction de remplacement sub().
La valeur reconnue se dsigne dans l'expression rgulire par un antislash suivi de son numro
(exemple : \5 pour la chane du groupe 5) ou par la convention de nommage :
(?P=identificateur)
Mais l'antislash suivi d'un chiffre peut avoir une signification en Python, il faut donc doubler
l'antislash dans la chane Python. Par ailleurs, cette notation devient ambigu avec les valeurs au
del de 10. Comment interprter \14 ? groupe 1 suivi de 4 ou groupe 14 ? Dans le patron le nombre
deux chiffres est correctement interprt comme "groupe 14" ; le groupe 1 suivi de 4 doit s'crire par
exemple \\1[4]. Pour la fonction sub(), voir le paragraphe 3.4.

3.2. exemple d'usage du numro


problme : trouver les mots d'un texte qui commencent et se terminent par la mme lettre.

#!/usr/bin/python3
import re

texte = "J'ai t en sursis et j'irai bien dsormais"

patron = "\\b(\w).*?\\1\\b"
cpatron = re.compile(patron)

while True :
print (texte)
res = cpatron.search(texte)
if res :
print (res.group(0))
texte = texte [res.end():]
else:
break

donne :

>>>
J'ai t en sursis et j'irai bien dsormais
t
en sursis et j'irai bien dsormais
sursis
et j'irai bien dsormais
irai
bien dsormais
>>>

E.R. en Python 3 fiche 3 : les groupes page 31


schma de la double analyse syntaxique avec groupe.

On a figur le groupe et la chane dont l'identification relve de l'analyse syntaxique.


3.3. usage de la convention de nommage.
exemple

#!/usr/bin/python3
import re

texte = "J'ai t en sursis et j'irai bien dsormais"

patron = "\\b(?P<premiereLettre>\w)\w*(?P=premiereLettre)\\b"
cpatron = re.compile(patron)

while True :
res = cpatron.search(texte)
if res :
print (res.group(0))
texte = texte [res.end():]
else:
break

donne :

>>>
t
sursis
irai
>>>

E.R. en Python 3 fiche 3 : les groupes page 32


3.4. la fonction de remplacement sub() avec capture.
On peut utiliser les lments capturs dans la chane de remplacement. Les conventions de
nommage sont alors :
\g<identificateur>
\g<numro>
Les symboles < et > ne sont pas indispensables si le numro n'a qu'un chiffre ; mais cette facilit est
viter cause de l'ambigut qui nat avec les valeurs deux chiffres.
Voici un problme d'illustration : on dispose d'un texte html, et on veut remplacer l'expression
align=center par une autre chane, mais uniquement dans les balises de bloc de texte, c'est--dire
commenant par h0,h1 ...h9 ou p. De plus, on veut liminer tout le reste des attributs de ces balises.

import re

texte = """<h1 name="titre"


align=CENTER>align=center</h1>
<img src="kw154.png" align = center>
<p align = center id="zazozi" >wawawa</p>
<h2 align= center>fin de texte</h2>"""

patron = """
(<h\d|<p) # balise commenant par <h avec chiffre ou <p
.*? # suite non gourmande de caractres
align\s*=\s*center # suivie du motif recherch
.*? # suite non gourmande de caractres
(>) # termine par >
"""
# le patron comporte deux groupes

cpatron = re.compile(patron, re.I+re.S+re.X) # IGNORECASE+DOTALL+VERBOSE


print (cpatron.findall(texte),"\n")

# les deux groupes sont utiliss dans la chane de remplacement.


res = cpatron.sub('\g<1> style=\'align:center;\' \g<2>', texte)

print (res)
>>>
[('<h1', '>'), ('<p', '>'), ('<h2', '>')]

<h1 style='text-align:center;' >align=center</h1>


<img src="kw154.png" align = center>
<p style='text-align:center;' >wawawa</p>
<h2 style='text-align:center;' >fin de texte</h2>
>>>

note : au lieu de numros, on aurait pu utiliser des identificateurs...

E.R. en Python 3 fiche 3 : les groupes page 33


fiche 4 : lookahead et lookbehind

1. Lookahead.
1.1. lookahead positif ou ngatif.
le problme :
Supposons que l'on dispose de l'expression rgulire patron mais que l'on veuille chercher une
correspondance conditionnelle : seulement si l'expression trouver est "suivie" (ou n'est pas suivie)
d'une expression trouve avec une autre expression rgulire hpatron.
Par exemple on cherche la chane "Isaac" suivie par "Newton" ou "Asimov". Ou le contraire.
videmment, on peut compliquer un peu.
Une telle recherche s'appelle un lookahead. Sa caractristique essentielle est qu'elle ne consomme
que la chane recherche, pas la chane conditionnelle.
La syntaxe est la suivante :
(?=expression lookahead recherche)
(?!expression lookehaed rejete)

1.2. lookahead postpos


exemple :
#!/usr/bin/python3
import re
texte = "isaac jacob, Isaac Newton, Isaac Asimov,\
isaac isaac\n, isaac Isaac"
patron ="Isaac\s(?=Asimov|Newton)"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))

patron ="Isaac(?:\s|$)(?!Asimov|Newton)"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))
>>>
['Isaac ', 'Isaac ']
['isaac ', 'isaac ', 'isaac\n', 'isaac ', 'Isaac']
>>>
* rappel \s pour un blanc (espace, fin de ligne).
* on voit bien sur le second cas qu'il n'y a pas consommation du lookahead.

1.3. lookahead prpos.


exemple 2 :

#!/usr/bin/python3
import re
texte = "isaac jacob, IsaacNewton, Isaac Asimov, bellisaac"
patron ="(?=\\bisa\w*\\b)isaac"
cpatron = re.compile(patron, re.IGNORECASE)

E.R. en Python 3 fiche 4 : lookahead et lookbehind page 34


print (cpatron.findall(texte))
>>>
['isaac', 'Isaac', 'Isaac']
>>>
* le patron du lookahead est d'abord recherch ; s'il est trouv, la recherche de la seconde partie du
patron se fait partir du premier lment trouv, qui est ici un dbut de mot. On dit qu'il y a
chevauchement.

2. Lookbehind.
2.1. lookbehind positif ou ngatif.
Une recherche de correspondance avec comme condition de suivre (ou non) une correspondance
dfinie par une autre expression rgulire est un lookbehind. Le lookbehind consomme l'expression
prcdente, mais ne la retourne pas. Il n'y a pas de chevauchement avec le lookbehind, car la chane
conditionnelle est avant la chane recherch.
Restriction : l'expression qui sert de condition doit avoir une longueur prfixe ; on ne peut
avoir de .* ou \w* ; mais on peut avoir toto|papa. Sinon, Il y a erreur la compilation.
syntaxe :
(?<=expression lookbehind recherche)
(?<!expression lookbehind rejete)

2.2. lookbehind prpos


exemple 1 :

#!/usr/bin/python3
import re
texte = "isaac jacob, IsaacNewton, IsaacAsimov, isaac"

patron ="(?<=isaac)[a-z]+"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))

donne :

>>>
['Newton', 'Asimov']
>>>
exemple 2

#!/usr/bin/python3
import re
texte = "isaac jacob, IsaacNewton, IsaacAsimov, mimieDany"

patron ="(?<=isaac|m[a-z]{4})[a-z]+"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))

E.R. en Python 3 fiche 4 : lookahead et lookbehind page 35


donne :

>>>
['Newton', 'Asimov', 'Dany']
>>>

2.2. lookbehind postpos.


problme : dans une liste de noms/prnoms, sortir les noms de 6 lettres prcdes par un prnom de
5 lettres.

#!/usr/bin/python3
import re
texte = "isaac jacob, Isaac Newton, Isaac La, Isaac Asimov"

motif ="\w{6}(?<=\w{5}\s\w{6})"
cmotif = re.compile(motif, re.IGNORECASE)
print (cmotif.findall(texte))
>>>
['Newton', 'Asimov']
>>>

Le mcanisme est le suivant : il y a d'abord recherche d'un mot de 6 lettres ; puis, partir du dernier
lment consomm, valuation de la condition lookbehind qui doit se terminer sur ce dernier lment
consomm. Il n'y a pas chevauchement puisque tout se passe avant le dernier lment consomm,
pas aprs comme dans le lookahead.

on a donc les 4 schmas possibles suivants :

E.R. en Python 3 fiche 4 : lookahead et lookbehind page 36

Vous aimerez peut-être aussi