Expressions régulières

Les expressions régulières

Une expression régulière (ou expression rationnelles) est un motif (un modèle, pattern en anglais) à comparer à une chaîne, ce qui peut réussir ou échouer.

  • Les expressions régulières sont utilisées par de nombreux programmes, comme les commandes UNIX grep, sed, awk, ed, vi, emacs, et même les divers shells.

  • Chaque programme possède un jeu de caractère de recherche de motifs (le plus souvent communs).

  • Python possède un sur-ensemble de fonctionnalités qui permet de réaliser des recherches très précises et puissantes.

  • Rechercher dans la chaîne "Petit exemple de ce que l'on peut faire avec les expressions régulières.", les motifs qui correspondent à :

    • une séquence qui commence par "ex" et se termine par "le"

    • les mots qui commencent par "ex"

    • les mots de quatre caractères de long

    • les mots sans majuscules

    • ...

Description des motifs

Un caractère

  • Le caractère de correspondance le plus simple et le plus courant dans les expressions régulières est un caractère qui correspond à lui même.

  • \ permet de définir littéralement un caractère qui sert normalement au codage : ( ) [ ] { } . $ ^ | ? + * \

Le point "."

Le point « » correspond à n'importe quel caractère unique, excepté « nouvelle ligne » (\n).

Le motif /a./ correspond à n'importe quel ensemble de deux lettres commençant par a et n'étant pas « a\n ».

Les crochets [ ]

Une classe de caractères de correspondance est représenté par une paire de crochets, ouvert et fermé, encadrant une série de caractères. Pour qu'il y ait correspondance avec les motifs, il faut et il suffit qu'un seul de ces caractères soit présent dans la partie correspondante.

/[abcde]/

correspond à une chaîne contenant n'importe laquelle des cinq premières lettres de l'alphabet en minuscule.

/[aeiouAEIOU]/

correspond à une chaîne contenant n'importe laquelle des cinq voyelles, en minuscules ou majuscules.

  • Pour insérer un crochet droit (]) dans la série, il faut le faire précéder d'une barre oblique inverse ou le mettre en première position de la série.

  • Les plages (intervalles) de caractères comme « de a à z » peuvent être abrégés en indiquant leur limites séparées par un tiret (-)

  • Pour avoir un tiret littéral dans la série il faut le faire précéder d'une barre oblique inverse ou le mettre à la fin

[0123456789] # correspond à n'importe quel caractère isolé

[0-9] # idem

[0-9\-] # correspond à 0-9, ou à moins

[a-zA-Z] # correspond à n'importe quelle lettre minuscule ou majuscule

[a-zA-Z0-9_] # correspond à n'importe quelle lettre, chiffre ou souligné

  • Il existe une classe d'exclusion de caractères, semblable à une classe de caractères, mais avec un accent circonflexe (^) situé immédiatement après le crochet gauche.

  • Cela correspond à tout caractère individuel non présent dans la série.

[^0-9] # correspond à tout sauf un chiffre

[^aeiouAEIOU] # correspond à tout sauf une voyelle

[^\^] # correspond à tout sauf à un accent circonflexe

  • Par commodité, certaines classes de caractères courantes sont pré-définies, comme le montre le tableau suivant :

    Construction

    Classe équivalente

    Constructeur de négation

    Classe de négation

    \d (un chiffre)

    [0-9]

    \D (pas un chiffre)

    [^0-9]

    \w (caractère de mot)

    [a-zA-Z0-9_]

    \W (pas un mot)

    [^a-zA-Z0-9_]

    \s (caractère espace)

    [ \r\t\n\f]

    \S (pas un espace)

    [^ \r\t\n\f]

  • Une classe abrégée peut-être utilisée dans d'autres classes

[\da-fA-F] # correspond à un chiffre hexadécimal

Motifs de regroupement

Série

La « série » correspond à une suite d'expressions régulières.

/abc/ # correspond un a suivi d'un b, suivi d'un c

Multiplicatifs

  • « * » indique zéro exemplaires ou plus du caractère (ou de la classe de caractères) qui le précède immédiatement.

  • « + » indique un ou plusieurs exemplaires du caractère qui le précède immédiatement.

  • « ? » signifie zéro ou un exemplaire du caractère qui le précède immédiatement.

/fo+ba?r/ # correspond à un f suivi d'un ou plusieurs o suivi d'un a optionnel, suivi d'un r

Ces trois motifs de regroupement sont « avides ». Si un tel multiplicatif peut correspondre à cinq ou dix caractères, il prendra toujours la chaîne

"fred xxxxxxxxxx barney" ;

/x+/

Multiplicatif général { }

Le multiplicatif général consiste en une paire d'accolades encadrant un ou deux nombres. Le caractère qui précède immédiatement doit être trouvé dans le nombre de répétitions indiqué par les accolades.

/x{5,10}/ # x doit être trouvé entre 5 et 10 fois/x{5,}/ # x doit être trouvé 5 fois au plus/x{0,5}/ # x doit être trouvé au moins 5 fois/x{5}/ # x doit être trouvé exactement 5 fois

*, + et ? peuvent donc aussi s'écrire {0,}, {1,} et {0,1} !

Avidité des opérateurs

  • Si deux multiplicatifs apparaissent dans une expression, la règle d'avidité est affinée par « le plus à gauche est le plus avide ».

  • On peut forcer un multiplicatif à être non avide (donc « paresseux ») en le faisant suivre d'un point d'interrogation. Tous les multiplicatifs sont éligibles : ?, +, * et {m,n}.

texte = "axyxcxxyxxzxxcxyzd" ;

/a.*c.*d/ # .*c correspond à "xyxcxxyxxzxxc"

/a.*?c.*d/ # .*?c correspond à "xyxc" seulement

  • Si une expression ne correspond pas, elle est ré-essayé sur une autre partie de la chaîne qui pourrait correspondre (système de « backtracking »).

  • Une expression régulière complexe peut conduire à de nombreux « backtrackings », allongeant la durée d'éxécution.

  • Une correspondance paresseuse (terminée par un « ? ») simplifiera réellement le travail de Python, tenez-en compte.

Parenthèses de mémorisation

Parenthèses de mémorisation

Une paire de parenthèses, encadrant une partie quelconque d'un motif, est un autre opérateur de regroupement. Elles ne modifient pas le fait que les motifs correspondent ou non, mais permet de mémoriser la partie correspondante au motif, afin que l'on puisse s'y référer ultérieurement. Pour manipuler une partie de chaîne mémorisée, il faut insérer une barre oblique inverse, suivie d'un entier. Une telle construction représente la série de caractères correspondant à la paire de parenthèses de même ordre (en comptant à partir de un).

/fred(.)barney\1/ # correspond avec "fredxbarneyx"

                  # mais pas avec "fredxbarneyz"

/fred.barney./    # correspond avec les deux

/a(.)b(.)c\2d\1/  # correspond avec "axbycydx"

/a(.*)b\1c/       # correspond avec "aFREDbFREDc" ou "abc"

                  # mais pas avec "aXXbXXXc"

Alternatives

Alternative : |

Une autre construction de regroupement est l'alternative représenté par le symbôle |

/a|b|c/ # idem /[abc]/

/chanson|bleu/ # correspond soit à chanson soit à bleu

Motifs d'ancrage

Motifs d'ancrage

Bloc ( ERT[{titre}] corps du bloc ) : Plusieurs notations particulières permettent d'ancrer un motif. Normalement lorsqu'un motif est mis en correspondance avec la chaîne, le début du motif est virtuellement déplacé de gauche à droite durant la comparaison avec la chaîne, entrant en correspondance à la première occasion possible. Les ancres permettent de s'assurer que certaines parties du motif sont alignées avec des parties particulières de la chaîne.

  • l'ancre \b correspond à une limite de mot

  • une limite de mot est l'endroit situé entre les caractères qui correspondent à \w et ceux correspondant à \W (ou entre \w et la fin de la chaîne)

  • l'ancre \B demande qu'il n'y aie pas de limite de mot à l'endroit indiqué

/fred\b/ ; # correspond à fred, mais pas à frederick

/\bmo/ ; # correspond à moe et à mole, mais pas à Elmo

/\bFred\b/ ; # correspond à Fred, mais pas à Frederick ni à AlFred

/\b\+\b/ ; # correspond à "x+y" mais pas à "++" ou à " + "

/abc\bdef/ ; # ne correspond jamais (impossible de trouver une limite ici)

/\bFred\B/ ; # correspond à "Frederick", mais pas à "Fred Flinstone"

  • ^ (accent circonflexe) correspond au départ de la chaîne (s'il est situé à un endroit censé correspondre à celà)

/^a/ ; # correspond au caractère a en début de chaîne

/a^/ ; # correspond à deux caractères a et ^ à n'importe quel endroit de la chaîne

  • $ correspond à l'ancre symbolisant la fin de chaîne (s'il est situé à un endroit censé correspondre à celà)

/c$/ ; # correspond au caractère c en fin de chaîne

/$c/ ; # correspond à deux acractères $ et c à n'importe quel endroit de la chaîne

  • D'autres ancres sont disponibles (\A et \Z) et des ancres de poursuite crées à partir de ?=... et ?!...

Précédente

Comme tous les opérateurs, les motifs de regroupement et d'ancrage disposent d'une précédence. Celle-ci est présentée dans le tableau ci-dessous, de la plus élevée à la plus faible.

Nom

Représentation

Parenthèses

() ( ? : )

Multiplicatifs

? + * {m,n} ?? +? *? {m,n}?

Série et ancrage

abc ^ $ \A \Z ( ? = ) ( ? ! )

Alternatives

|

/a|b*/ un seul a ou n'importe quelle quantité de b

/abc*/ correspond à ab, abc, abcc, abccc, etc.

/(abc)*/ correspond à "", abc, abcabc, abcabcabc, etc.

/^x|y/ correspond à x en début de ligne ou à y ailleurs

/^(x|y)/ correspond à x ou à y au début d'une ligne

/a|bc|d/ a, ou bc, ou d

/(a|b)(c|d)/ ac, ad, bc ou bd

/(song|blue)bird/ songbird ou bluebird

Implémentation Python

  • utilisation de " possible : mais interprétation des \ sur les caractères spéciaux des chaînes de caractères, ce qui oblige à les doubler

  • préférer l'utilisation de r' ' qui permet d'écrire des expressions régulières sans se préoccuper des interprétations de \

1. ne marche pas avec ":

rep= re.search("\b\w+\b",'un exemple simple')

2. meme exemple qui marche :

rep= re.search("\\b\w+\\b",'un exemple simple')

3. avec r' ' :

rep= re.search(r'\b\w+\b','un exemple simple')

Recherche d'expressions régulières en Python : match

match

match permet la comparaison stricte d'un motif et d'une chaîne.

import re

rep= re.match("12",'aBCDE123')

if rep: print(rep.group())

import re

rep=re.match(".*7",'abcd7e7')

if rep: print(rep.group())

rep=re.match(".*?7",'abcd7e7')

if rep: print(rep.group())

Recherche d'expressions régulières en Python : search

search

search permet de savoir si un motif se retrouvent au moins une fois dans une chaîne.

import re

rep=re.search("[A-Z]{4}\d+?",'aBCDE123')

if rep: print(rep.group()) # "4 majuscules et au moins un chiffre" est bien inclus dans 'aBCDE123'

Dans l'exemple, le ? limite la réponse à BCDE1

Recherche d'expressions régulières en Python : findall

findall

findall permet de récupérer tous les motif se retrouvent dans une chaîne.

>>> text = "He was carefully disguised but captured quickly by police."

>>> re.findall(r"\w+ly", text)

['carefully', 'quickly']

Rechercher/remplacer en Python

sub

sub(motif,rempl,chaine,n) permet des substitutions dans une chaîne, avec une éventuelle limite d'occurrence.

import re

print(re.sub("[A-Z]{2}",'0','ABCDE123')) # tout couple de majuscules sera remplacé par 0

subn

subn effectue la même opération, mais rend un tuple avec la nouvelle chaîne et le nombre de remplacements effectués

Découper en Python

split

split(motif,chaine,n) débite une chaîne dans une liste, avec une éventuelle limite d'occurrence

import re

print(re.split("\d{2}",'ab92cde14ze')) # le séparateur est ici toute chaîne de deux chiffres

Options des expressions régulières en Python

  • flags (ignorer casse, multiligne)

  • utilisation de plusieurs lignes et commentaires

Il est possible de compiler préalablement le motif, pour ensuite utiliser en préfixe des fonctions

import re

motif=re.compile("\d{2}")

print(motif.split('ab92cde14ze'))

Exercices

Exercices expressions régulières

  1. Écrire les expressions régulières correspondant à :

    1. 3 A suivi de n'importe quel caractère parmi A, C, G ou T, terminé par un C

    2. A ou C suivi d'un caractère quelconque, pouvant être suivi par des T

    3. un C suivi de n'importe quel carctère sauf G, suivi d'un nombre de A pouvant aller de 3 à 5

    4. une séquence de 3 bases A, C, G ou T qui se trouve répétée deux fois dans une séquence ADN

    5. un mot de 2 lettres dans une phrase du type : « Ceci est un exemple de phrase test »

    6. tous les espaces d'une phrase

    7. touts les caractères n'étant pas des caractères alphanumériques

  2. Écrire un programme Python pour rechercher une expression régulière et afficher le motif qui est en correspondance.

  3. Écrire un programme Python pour rechercher une expression régulière et remplacer les motifs par une chaîne. L'appliquer à la suppression des caractères d'espacement dans une phrase.

  4. Écrire un sous programme qui permette de transcrire une chaîne ADN en ARN.

  5. Réécrire le sous-programme qui permet de transformer des codons en acides aminés en utilisant des expressions régulières.

  6. Écrire une nouvelle version en factorisant au maximum les expressions régulières et en ayant plus qu'une seule expression par acide aminé.

AccueilProgrammation en Python > Expressions régulières< PrécédentSuivant >