• Keine Ergebnisse gefunden

Quelques fonctions associées aux expressions régulières

Tout comme pour la fonction str() dans le cas du traitement direct des chaînes de caractères, il y a aussi plusieurs fonctions associées à re. Ci-dessous la description de quelques-unes.

2.2.5.1. La fonction search()

119 La fonction head( permet de rechercher le motif (pattern) au sein d’une chaîne de caractères avec une syntaxe de la forme search(motif, chaine). Si motif existe dans chaine, Python renvoie une instance MatchObject.

Exemple 1:

animaux = "girafe tigre singe"

x=re.search('tigre', animaux)

print(x) # donne _sre.SRE_Match object; span=(7, 12), match='tigre'>.

Ce qui signifie que le mot a été bien trouvé Exemple2: test

if re.search('tigre', animaux):

print "OK"

Exemple 3: recherche chaines commençant par b ou B

z=re.compile(r"[bB][a-zA-Z]*") # chaines commençant par b ou B suivies de n'importe quelles lettres de a-z ou A-Z

phrase = "Zorro zozotte contrairement à Bernardo"

x=z.search(phrase) # on cherche la premiere occurence de l'objet z dans phrase

print(x) " donne _sre.SRE_Match object; span=(30, 38), match='Bernardo'

Exemple 4 : On veut trouver toutes les occurences du mot "tache" dans le texte suivant : phrase = "Qui mange avec une moustache se tache."

z = re.compile(r"tache")

x=z.search(phrase) # on cherche la premiere occurence de l'objet z dans phrase

print(x)

Exemple 5 : On veut trouver toutes les postions des occurences du mot "tache" . On ajoute la fonction span

z = re.compile(r"tache")

z.search(phrase).span() # retourne 23,28

Le problème avec la fonction search est que l’on trouve la première occurence, même si elle est dans un autre mot. Pour éviter ce problème on peut utiliser \b qui est un délimiteur de début ou de fin de mot:

z = re.compile(r"\btache\b")

x=z.search(phrase).span() # retourne 32,37

# \B sert à s’assurer que l’on est pas un début ou une fin de mot ( c'est la situation négative de \b) :

texte = "Une moustache on s'y attache, même si ça tache."

120 p = re.compile(r"\w*\Btache\w*|\w*tache\B\w*")

x=p.findall(texte)

print(x) # renvoie ['moustache', 'attache']

2.2.5.2. La fonction match()

Dans le module re, la fonction match()fonctionne comme la fonction search(). La différence est qu’elle renvoie une instance MatchObject seulement lorsque l’expression régulière correspond (match) au début de la chaîne (à partir du premier caractère).

Exemple 1:

z=re.compile(r"[bB][a-zA-Z]*") # chaines commençant par b ou B suivies de n'importe quelles lettres de a-z ou A-Z

phrase = "Zorro zozotte contrairement à Bernardo"

x=z.match("Bernardo") # renvoie None si aucun prefixe n'est reconnaissable par l'expression

Exemple 2:

animaux = "girafe tigre singe"

re.match('tigre', animaux)

Utilisation comparée des fonctions match er search

La recherche (search()) consiste à parcourir le texte depuis le début ; si le pattern 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 début du texte au pattern. 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 méthodes. Pour l'instant, les méthodes start() (premier caractère reconnu) et stop() (position après le dernier caractère reconnu) Exemple:

texte = "Un IDE ou \"environnement de développement\" est un logiciel

\

constitué d'outils qui facilitent l'écriture et les tests dans un \ langage défini, voire plusieurs.\

\nCet IDE comporte en général un éditeur avec coloration syntaxique,\

un système de gestion de fichiers (sauvegarde/chargement),\

un compilateur, un exécuteur de programme, un système d'aide en ligne,\

des indicateurs de syntaxe etc. \

\nLe plus connu est peut être Éclipse."

Recherche du pattern dans le texte ; résultat affiché : 158 165

121 pattern = "Cet IDE"

cpattern = re.compile(pattern) resultat = cpattern.search(texte) if resultat :

print(resultat.start(), resultat.end()) else:

print (resultat)

Comparaison du pattern au texte ; résultat affiché : None resultat = cpattern.match(texte)

if resultat :

print(resultat.start(), resultat.end()) else :

print(resultat)

Comparaison du pattern au texte ; résultat affiché : 0 6 pattern = "Un IDE"

cpattern = re.compile (pattern) resultat = cpattern.match(texte) if resultat :

print(resultat.start(), resultat.end()) else :

print (resultat)

Recherche en ignorant la casse ; résultat affiché : 413 420 pattern = "éclipse"

cpattern = re.compile (pattern, re.IGNORECASE) resultat = cpattern.search(texte)

if resultat :

print(resultat.start(), resultat.end()) else:

print(resultat)

2.2.5.3. La fonction findall()

Cette fonction recherche et retourne tous les éléments qui correspondent dans une liste de chaînes.

Exemple 1 :

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

resultat = regex.findall("pi vaut 3.14 et e vaut 2.72") print(resultat) # donne ['3.14', '2.72']

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

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

122 print(resultat) # donne [('3', '14'), ('2', '72')]

Exemple 2 : soit la chaine suivante

phrase = "Zorro zozotte contrairement à Bernardo"

Définissons deux re telles que:

a=re.compile(r"[\w]+") # mots d'au moins une lettre de \w toutes ie.

toutes les lettres (y compris accents)

b=re.compile(r"[bB][a-zA-Z]*") # chaines commençant par b ou B suivies de n'importe quelles lettres de a-z ou A-Z

Application de la fonction findall

x=a.findall(phrase) # on cherche tous les a dans phrase et renvoie une liste de ceux-ci

y=b.findall(phrase)

Exemple 3: on dispose d'une liste de noms de localités 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. Les villes en questions sont indiquées comme suit:

Ablon Acqueville Agy

Aigner-Ville Airan

Amayé-sur-Orne Amblie

Amfreville Angervillers Angoville Résolution :

On peut constituer le texte à partir de cette liste de villes comme suit :

texte ="Ablon\nAcqueville\nAgy\nAigner-Ville\nAiran\nAmayé-sur-Orne\

\nAmblie\nAmfreville\nAngervillers\nAngoville\nArganchy\nArgences\

\nArromanches-les-Bains\nAsnelles\nAsnières-Surville"

Définition du motif : pattern = ".*ville$"

123 cpattern = re.compile (pattern)

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

cpattern = re.compile (pattern, re.MULTILINE) resultat = cpattern.findall(texte)

print (resultat, "\n")

cpattern = re.compile (pattern, re.MULTILINE+re.IGNORECASE) resultat = cpattern.findall(texte)

print (resultat, "\n")

On a: ".*ville$" : une suite de caractères, suivie de ville, suivie de la fin de texte. Les fins de chaîne ne sont pas incluses. Seule la dernière ligne peut être prise en compte si on ne met pas de directives !

2.2.5.4. La fonction fonction sub()

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 on souhaite ne remplacer que les n premières occurrences, on utilise l’argument count=n : sub(chaine1,chaine2, n).

Exemple 1 :

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

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

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

Exemple2

texte = "Retourne le texte avec ses remplacements. La \ valeur remplacement est une chaîne (qui peut être obtenue \ par application d'une fonction, appelée à chaque \

remplacement). count donne le maximum de remplacements ; \

0 est la valeur par défaut et signifie que tous les remplacements\

possibles doivent être effectués."

pattern= "\. " # antislash de protection du point remplacement ="\n\n"

cpattern = re.compile(pattern)

nouveau = cpattern.sub(remplacement, texte) print (nouveau)

print ("\n************************************\n") retTuple = cpattern.subn (remplacement, texte)

print (retTuple)

2.2.5.5. La fonction findinter()

124 Cette fonction agit comme findall() mais renvoie un itérateur.

Exemple :

b=re.compile(r"[zZ][a-zA-Z]")

phrase = "Zorro zozotte contrairement à Bernardo"

h=b.finditer(phrase) # comme findall mais renvoie un itérateur

2.2.5.6. La fonction group()

Il arrive souvent qu’on veuille récupérer la valeur d’un mot ou d’un ensemble de mots qui matche une partie de l’expression régulière. Pour cela les expressions régulières offrent la possibilité de créer des groupes de motifs à conserver.

Exemple : Conserver le suffixe des verbes se terminant par aient.

s = 'ils allaient et bavardaient en cheminant'

rgx = r'(\w*)aient\b' # Le groupe que l’on veut conserver est indiqué entre ()

for m in re.finditer(rgx,s) : print m.group(0), m.group(1) Les résultats sont: allaient all ; bavardaient bavard

groupe(0) est l’expression entière, groupe(1) correspond au premier groupe demandé (ici un seul).

Exemple 2 :

regex = re.compile('([0-9]+)\.([0-9]+)') resultat = regex.search("pi vaut 3.14") resultat.group(0) # donne 3.14

resultat.group(1) # donne 3 resultat.group(2) # donne 14 resultat.start() # donne 8 resultat.end() # donne 12

Dans cet exemple, on recherche un nombre composé de plusieurs chiffres [0-9]+ \. (le point a une signification comme métacaractère, donc il faut l’échapper avec \ pour qu’il ait une signification de point), suivi d’un nombre à plusieurs chiffres [0-9]+. Les parenthèses dans l’expression régulière permettent de créer des groupes qui seront récupérés ultérieurement par la fonction group(). La totalité de la correspondance est donné par group(0), le premier élément entre parenthèse est donné par group(1) et le second par group(2). Les fonctions start() et end() donnent respectivement la position de début et de fin de la zone qui correspond à l’expression régulière. Notez que la fonction search() ne renvoie que la première zone qui correspond à l’expression régulière, même s’il en existe plusieurs :

125 resultat = regex.search("pi vaut 3.14 et e vaut 2.72")

resultat.group(0) # donne 3.14

NB : Certains caractères spéciaux dans nos expressions régulières sont modélisés par l'anti-slash \. Vous savez sans doute que Python représente d'autres caractères avec ce symbole. Si vous écrivez dans une chaîne \n, Python effectuera un saut de ligne ! Pour symboliser les caractères spéciaux dans les expressions régulières, il est nécessaire d'échapper l'anti-slash en le faisant précéder d'un autre anti-slash. Cela veut dire que pour écrire le caractère spécial \w, vous allez devoir écrire \\w. C'est assez peu pratique et parfois gênant pour la lisibilité. C'est pourquoi on peut utiliser le mot clé r avant le délimiteur qui ouvre notre chaîne, tous les caractères anti-slash qu'elle contient sont échappés.

Exemple:

r' \n' r' \texte'

Ci-dessous quelques opérateurs d’échappement de caractères spéciaux dans les regex :

\ symbole d’échappement

\e séquence de contrôle escape

\f saut de page

\n fin de ligne

\r retour-chariot

\t tabulation horizontale

\v tabulation verticale

\d classe des nombres entiers

\s classe des caractères d’espacement

\w classe des caractères alphanumériques

\b délimiteurs de début ou de fin de mot

\D négation de la classe \d

\S négation de la classe \s

\W négation de la classe \w

\B négation de la classe \b

126

2.2.6. Etude de quelques expressions régulières couramment