CPGE Oujda                                                                                                                                                                         Spé

Initiation aux expressions régulières

Si on demande à l'utilisateur de fournir un numéro de téléphone ? Qu'est-ce qui l'empêche de taper n'importe quoi ? Si on lui demande de fournir une adresse e-mail et qu'il tape quelque chose d'invalide, que va-t-il se passer ? Si ce cas n'est pas géré, vous risquez d'avoir un problème. Les expressions régulières sont un moyen de rechercher, d'isoler ou de remplacer des expressions dans une chaîne.

Quelques éléments de syntaxe pour les expressions régulières

Le module re,  nous permet de faire des recherches très précises dans des chaînes de caractères et de remplacer des éléments de nos chaînes, le tout en fonction de critères particuliers. Ces critères, ce sont nos expressions régulières. Pour nous, elles se présentent sous la forme de chaînes de caractères.

Rechercher au début ou à la fin de la chaîne

Vous pouvez rechercher au début de la chaîne en plaçant en tête de votre regex (abréviation de Regular Expression) le signe d'accent circonflexe ^. Si, par exemple, vous voulez rechercher la syllabe cha en début de votre chaîne, vous écrirez donc l'expression ^cha. Cette expression sera trouvée dans la chaîne 'chaton' mais pas dans la chaîne 'achat'.  Pour matérialiser la fin de la chaîne, vous utiliserez le signe $. Ainsi, l'expression q$ sera trouvée uniquement si votre chaîne se termine par la lettre q minuscule.

Contrôler le nombre d'occurrences

exemple  :  chat*

Cela signifie que notre lettre t pourra se retrouver 0, 1, 2, … fois dans notre chaîne. Ex : 'herbe à chat', 'chatterton', 'chattttttttt'

Un autre exemple ? :  bat*e : Cette expression est trouvée dans les chaînes suivantes : 'bateau', 'batteur' .

Dans nos exemples, le signe * n'agit que sur la lettre qui le précède directement, pas sur les autres lettres qui figurent avant ou après.

Il existe d'autres signes permettant de contrôler le nombre d'occurrences d'une lettre.

Signe

Explication

Expression

Chaînes contenant l'expression

*

0, 1 ou plus

abc*

'ab', 'abc', 'abcc', 'abcccccc'

+

1 ou plus

abc+

'abc', 'abcc', 'abccc'

?

0 ou 1

abc?

'ab', 'abc'

Vous pouvez également contrôler précisément le nombre d'occurrences grâce aux accolades :

Les classes de caractères

Vous pouvez préciser entre crochets plusieurs caractères ou classes de caractères. Par exemple, si vous écrivez [abcd], cela signifie : l'une des lettres parmi a, b, c et d.

Pour exprimer des classes, vous pouvez utiliser le tiret - entre deux lettres. Par exemple, l'expression [A-Z] signifie « une lettre majuscule ». Vous pouvez préciser plusieurs classes ou possibilités dans votre expression. Ainsi, l'expression [A-Za-z0-9] signifie « une lettre, majuscule ou minuscule, ou un chiffre ».   Vous pouvez aussi contrôler l'occurrence des classes . Si vous voulez par exemple rechercher 5 lettres majuscules qui se suivent dans une chaîne, votre expression sera [A-Z]{5}.

Les groupes

si vous voulez appliquer ce contrôle d'occurrence à plusieurs caractères, vous allez placer ces caractères entre parenthèses.  (cha){2,5}

Cette expression sera vérifiée pour les chaînes contenant la séquence 'cha' répétée entre deux et cinq fois. Les séquences 'cha' doivent se suivre naturellement.

Les groupes sont également utiles pour remplacer des portions de notre chaîne .

Le module re :

Le module re a été spécialement conçu pour travailler avec les expressions régulières (Regular Expressions). Il définit plusieurs fonctions utiles  ainsi que des objets propres pour modéliser des expressions.

Chercher dans une chaîne

Nous allons pour ce faire utiliser la fonction search du module re. Bien entendu, pour pouvoir l'utiliser, il faut l'importer.      >>> import re

La fonction search attend deux paramètres obligatoires : l'expression régulière, sous la forme d'une chaîne, et la chaîne de caractères dans laquelle on recherche cette expression. Si l'expression est trouvée, la fonction renvoie un objet symbolisant l'expression recherchée. Sinon, elle renvoie None.

Certains caractères spéciaux dans nos expressions régulières sont modélisés par l'anti-slash \. pour écrire le caractère spécial \w, vous allez devoir écrire \\w.

on peut aussi  mettre un r avant d'écrire des chaînes contenant des expressions.

>>> re.search(r"abc", "abcdef")      à  <_sre.SRE_Match object at 0x00AC1640>

>>> re.search(r"abc", "abacadaeaf")

>>> re.search(r"abc*", "ab")             à<_sre.SRE_Match object at 0x00AC1800>

>>> re.search(r"abc*", "abccc")        à <_sre.SRE_Match object at 0x00AC1640>

>>> re.search(r"chat*", "chateau")   à <_sre.SRE_Match object at 0x00AC1800>

si l'expression est trouvée dans la chaîne, un objet de la classe _sre.SRE_Match est renvoyé. Si l'expression n'est pas trouvée, la fonction renvoie None.

if re.match(expression, chaine) is not None:# Si l'expression est dans la chaîne 

# Ou alors, plus intuitivement    if re.match(expression, chaine):

par exemple, comment obliger l'utilisateur à saisir un numéro de téléphone ?

Notre regex doit vérifier qu'une chaîne est un numéro de téléphone. L'utilisateur peut saisir un numéro de différentes façons :

Autrement dit :

Voici la regex:   ^0[0-9]([ .-]?[0-9]{2}){4}$

import re

chaine = ""

expression = r"^0[0-9]([ .-]?[0-9]{2}){4}$"

while re.search(expression, chaine) is None:

    chaine = input("Saisissez un numéro de téléphone (valide) :")

Compilation d'expressions régulières

Il est aussi commode de préalablement compiler l'expression régulière à l'aide de la fonction compile() qui renvoie un objet de type expression régulière :

>>> regex = re.compile("^tigre")

>>> regex

<_sre.SRE_Pattern object at 0x7fefdafd0df0>

On peut alors utiliser directement cet objet avec la méthode search() :

>>> animaux = "girafe tigre singe"

>>> regex.search(animaux)

>>> animaux = "tigre singe"

>>> regex.search(animaux)

<_sre.SRE_Match object at 0x7fefdaefe718>

>>> animaux = "singe tigre"

>>> regex.search(animaux)

Fonction findall()

Pour récupérer chaque zone, vous pouvez utiliser la fonction findall() qui renvoie une liste des éléments en correspondance.

>>> regex = re.compile('[0-9]+\.[0-9]+')

>>> resultat = regex.findall("pi vaut 3.14 et e vaut 2.72")

>>> resultat

['3.14', '2.72']

>>> regex = re.compile('([0-9]+)\.([0-9]+)')

>>> resultat = regex.findall("pi vaut 3.14 et e vaut 2.72")

>>> resultat

[('3', '14'), ('2', '72')]

Fonction sub()

Enfin, la fonction sub() permet d'effectuer des remplacements assez puissants. Par défaut la fonction sub(chaine1,chaine2) remplace toutes les occurrences trouvées par l'expression régulière dans chaine2 par chaine1. Si vous souhaitez ne remplacer que les n premières occurrences, utilisez l'argument count=n :

>>> regex.sub('quelque chose',"pi vaut 3.14 et e vaut 2.72")

'pi vaut quelque chose et e vaut quelque chose'

>>> regex.sub('quelque chose',"pi vaut 3.14 et e vaut 2.72", count=1)

'pi vaut quelque chose et e vaut 2.72'

 

Autres  symboles qui ont une signification:

 (x|y) Indique un choix multiple type (ps|ump) équivaut à "ps" OU "UMP"

\d    le segment est composé uniquement de chiffre, ce qui équivaut à [0-9].

\D    le segment n'est pas composé de chiffre, ce qui équivaut à [^0-9].

\s    Un espace, ce qui équivaut à [ \t\n\r\f\v].

\S    Pas d'espace, ce qui équivaut à [^ \t\n\r\f\v].

\w    Présence alphanumérique, ce qui équivaut à [a-zA-Z0-9_].

\W    Pas de présence alphanumérique [^a-zA-Z0-9_].

 

Exercice :

Validation d’une adresse email avec la syntaxe :

Syntaxe :nom@site.type avec type composé de 2 a 4 caractères (.com,.fr,…)

 

 

Solution :

Re.findall(r’\w+@\w+.\w{2,4}’,’dan@tr.com’)