En Big Data, la recherche des données pertinentes est l’une des tâches primordiales à effectuer. Le Data Analyst et/ou le Data Engineer se basent sur les données collectées en amont pour pouvoir tirer des conclusions qui vont aider les métiers à la prise de décision. Cependant, pour qu’une analyse soit effective, il faut s’assurer de la véracité des données extraites.
Dans la plupart des cas, ces données sont centralisées dans des bases de données exploitées encore dans une grande majorité de cas par des systèmes de gestion de bases de données relationnelles (SGBDR). Les SGBDR, en s’appuyant sur le SQL, offrent des fonctionnalités de recherche de contenu qui sont très limitées à la fois en termes de type, de varieté de contenu et de volume. Une première approche pour extraire de l’information c’est d’utiliser un moteur de recherche de contenu comme Elasticsearch. L’efficacité de ce type de moteur repose sur des expressions particulières appelées des expressions régulières ou Regex.
Posons les bases. A l’époque, pour effectuer les recherches sur une base de données, il fallait utiliser des requêtes qui se basent essentiellement sur des mots clés. C’est ce qui explique la pré-éminence du SQL. Sauf que depuis que le Big Data a pris de l’ampleur, ce type de fonctionnement ne suffit plus.
Imaginez que vous recherchiez une chanson que vous avez entendue à la radio et que vous souhaitiez le retrouver sur internet sans connaitre exactement la référence à taper. Si on se base exclusivement sur la méthode orientée mot-clé, il sera difficile d’obtenir le résultat attendu.
Un autre exemple, imaginez que dans une application que vous êtes en train de concevoir, vous souhaitez vérifier si la personne a saisi une adresse email ou un numéro de téléphone valide. Il vous faudra écrire une expression très complexe. Les expressions régulières interviennent donc pour faciliter la rédaction des expressions de recherche de contenu.
Dans ce tutoriel exhaustif, nous allons vous montrer ce qu’est une expression régulière. Quelles sont les syntaxes à utiliser et comment les utiliser en Python, car oui, Python est devenu un langage incontournable en Big Data.
Expression régulière : c’est quoi ?
Regardez ce bout de code :
expression = r"\"?([-a-zA-Z0-9.`?{}]+@\w+\.\w+)\"?"
Vous devez vous demander ce qu’est cette écriture bizarre ! Et bien, c’est une expression régulière qui servira à vérifier si une adresse email est valide (qu’elle contienne un « @ », un « . », etc.).
Une expression régulière (ou expression rationnelle, expression normale, motif ou encore RegEx pour regular expression) est un ensemble de caractère servant à vérifier si une expression correspond à une structure préalablement décrite.
C’est un outil, ou plutôt un langage dérivé du langage Perl, extrêmement puissant qui permet d’effectuer des recherches plus poussées ou plus élargies sur une base de données volumineuse. A l’aide d’une seule expression régulière, on peut tirer plusieurs résultats sans pour autant sortir du contexte initial.
On peut utiliser les expressions régulières dans presque n’importe quel langage, y compris Python, dès que l’on a appris à maitriser ses syntaxes. Vous n’aurez donc pas à vous tracasser si vous concevez des solutions à l’aide de plusieurs langages. D’ailleurs, si vous souhaitez diversifier vos compétences en matière de langage de programmation, vous pouvez apprendre la programmation Java avec notre guide complet.
Quand utiliser les expressions régulières ?
Les expressions régulières s’utilisent dans des domaines divers et variés. En effet, on peut s’en servir pour :
- Des recherches de correspondances ;
- Le remplacement d’expression ;
- L’analyse de données ;
- La validation de données ;
- Et le changement de formats
En Big Data, on retrouve souvent les expressions régulières dans le domaine du Data Mining. Elles sont utilisées dans les outils pour spécifier les champs de recherches sur lesquels se baser. Nous vous l’apprenons plus en détail dans notre article sur le Data Mining.
Les différentes syntaxes des regex
Maintenant que nous avons contextualisé les choses, nous pouvons passer à la pratique. Dans cette rubrique, nous allons vous donner les syntaxes à utiliser pour créer une regex en Python.
Pour écrire une expression régulière, on peut la formuler à l’aide d’un motif simple, c’est-à-dire en définissant exactement la chaine de caractère à rechercher ou bien en utilisant certaines syntaxes à savoir : les métacaractères, les quantificateurs et les classes.
Motif simple
Un motif est dit simple lorsque l’on précise la chaine à valider dans notre expression régulière. Par exemple, si l’on souhaite trouver une correspondance pour « data », avec exactement les mêmes suites de caractère, on le formule comme suit :
expression = re.compile('data')
Utilisation des caractères spéciaux
Les métacaractères
Il existe quelques caractères qui, lorsque nous formulons nos expressions régulières, présentent un sens spécifique autre que le caractère lui-même. Voici ces caractères et leurs significations :
^ :précise que le résultat doit commencer par la chaine de caractères qui le suit ;
$ : précise que le résultat doit se terminer par la chaine de caractère qui le précède ;
. : correspond à n’importe quel caractère sauf le saut de ligne.
Les quantificateurs
Il existe également certains caractères qui sont considérés comme des quantificateurs. Ces caractères sont :
+ : qui signifie que le résultat peut contenir une ou plusieurs occurrences du caractère qui le précède ;
* : qui veut dire que le résultat peut contenir zéro ou plusieurs occurrences du caractère qui le précède ;
? : qui signifie que le résultat peut inclure zéro ou une occurrence du caractère qui le précède ;
{} : qui permet de préciser le nombre de nombres de répétitions des chaines de caractères qui le précède ;
[ ] : qui permet d’obtenir le résultat sur plusieurs occurrences.
Les opérateurs
Il existe également quelques opérateurs que l’on peut utiliser lorsqu’on rédige une expression régulière. Parmi eux, il y’a :
| : qui correspond à l’expression OU. On peut s’en servir pour trouver une correspondance entre deux ou plusieurs expressions. Par exemple, le RegEx (big|data) retournera les chaines de caractères qui contiennent l’expression big ou data.
– : qui sert à regrouper des caractères dans un intervalle donné. On le retrouve souvent dans les intervalles de classes que nous allons voir un peu plus bas.
\ : qui sert à échapper un caractère spécial, c’est-à-dire à redonner le sens propre d’un caractère utilisé pour d’autres fonctions dans la Regex. Toutefois, en Python, ce caractère représente déjà cette fonction, ce qui complique un peu les choses, surtout lorsque l’on souhaite l’échapper lui-même. Pour cela, il faut écrire ////. Pour remédier à ce désagrément, il faut juste précéder l’expression de r et le tour est joué comme cela :
import re
regex = r"\\test"
Les classes
Les classes permettent de préciser les champs de recherche sur lesquels on souhaite obtenir un résultat. Par exemple, on peut spécifier la recherche de certaines lettres de l’alphabet ou d’une plage de nombre prédéfini dans une expression.
Il existe plusieurs manières d’exprimer une classe comme les intervalles de classes, les classes abrégées ou les classes nommées.
Les intervalles de classe
Ils sont contenus entre des crochets ( [ ] ), ils permettent de spécifier les caractères à inclure dans le résultat des recherches. Ils peuvent également définir les caractères à exclure si on les précède du caractère ^. Par exemple, [ab] peut définir le caractère a ou b, [0-9] représente l’ensemble des chiffres se trouvant entre 0 et 9.
Les classes abrégées
Ils effectuent les mêmes procédés, sauf que l’écriture est plus courte et plus lisible. Voici la liste des classes abrégées :
Syntaxes | Signification |
---|---|
\w | tous les caractères alphabétiques |
\W | tous les caractères non alphabétiques |
\d | tous les caractères numériques |
\D | tous les caractères non numériques |
\s | tous les caractères blancs (saut de page, tabulation, retour à la ligne, retour chariot, espace vertical) |
\S | tous les caractères non blancs |
\A | le début d’une chaine de caractères |
\Z | la fin d’une chaine de caractères |
\t | tabulation horizontale |
\v | espace vertical |
\n | retour à la ligne |
\r | retour chariot |
\f | saut de page |
Les classes nommées
Elles suivent la même logique et comme les classes abrégées, elles servent également à obtenir une meilleure lisibilité de l’expression régulière. Vous trouverez dans le tableau ci-dessous quelques classes abrégées :
Syntaxes | Signification |
---|---|
[[:digit:]] | représente n’importe quel chiffre |
[[:xdigit:]] | représente les caractères hexadécimaux |
[[:alpha:]] | représente n’importe quel caractère alphabétique |
[[:alnum:]] | représente n’importe quel caractère numérique ou alphabétique |
[[:space:]] | représente un espace |
[[:punct:]] | représente un signe de ponctuation |
[[:lower:]] | représente les minuscules |
[[:upper:]] | représente les majuscules |
Pour avoir plus de détails sur les syntaxes d’expression régulière en Python, vous pouvez consulter la documentation sur le module re que nous allons aborder brièvement dans un instant.
Les regex avec Python
Dans cette rubrique, nous allons vous montrer comment mettre en pratique ces regex avec Python. Si vous n’êtes pas à l’aise en Python, pas de soucis, consultez notre tutoriel complet sur le sujet en cliquant sur le lien suivant : programmation Python.
Le module re
Ce module est celui qu’il faut importer dans votre programme Python pour que vous puissiez utiliser les expressions régulières avec ce langage de programmation.
En réalité, c’est un module d’extension du langage C qui a été inclus dans Python. Les expressions régulières vont être compilées en bytecode puis exécutées par un moteur de correspondance en C.
Grâce au module re, Python rend possible la manipulation des chaines Unicode et des chaines 8-bits. Vous pouvez effectuer plusieurs tâches telles que la recherche de correspondance, le remplacement de chaines de caractères ou bien le découpage des chaines en plusieurs morceaux.
Les fonctions du module re
Entrons dans le vif du sujet, c’est-à-dire, la mise en pratique des regex avec Python. Ici, nous allons vous donner quelques exemples d’utilisation des Regex avec Python.
La fonction de compilation d’une regex en Python
Pour initialiser une expression régulière avec Python, vous pouvez le compiler, surtout si vous serez amené à l’utiliser plusieurs fois tout au long de votre programme. Pour ce faire, il faut utiliser la fonction compile() comme suit :
x = re.compile(expression)
Vous pouvez spécifier un deuxième paramètre à la fonction compile() qui fera changer le comportement de l’expression suivant ce dernier. Ces paramètres sont appelés Flags. Parmi eux, nous avons : « ASCII, A », « DOTALL, S », « IGNORECASE, I », « LOCALE, L », « MULTILINE, M » et « VERBOSE, X ».
Reprenons notre exemple précédent, à savoir compiler l’expression « data », et ajoutons-y le paramètre INGNORECASE :
x = re.compile(expression, re.INGORECASE)
Ici, vous obtiendrez une expression qui sera insensible à la casse. Le résultat des opérations sur cette expression pourra donc être data, Data, DATA, etc.
Les fonctions de recherche de correspondance
Pour effectuer une recherche de correspondance, il existe plusieurs méthodes.
Vous pouvez, par exemple utiliser la méthode match() pour connaitre si une chaine de caractère peut correspondre à une expression donnée :
import re
chaine = "Bonjour tous le monde"
req = re.match(r"bonjour", strTest, re.I)
print(req.group())
Ici, il recherche s’il existe une chaine de caractère commençant par bon en précisant que la casse n’est pas considérée. Il va donc retourner Bonjour.
Vous pouvez également utiliser search() pour effectuer des recherches sur une chaine de caractère. Contrairement à match(), search() va rechercher sur tous l’ensemble de la chaine mais pas seulement au début.
import re
chaine = "Bonjour tous le monde"
req = re.search(r"tous", chaine, re.I)
print(req.group())
Une fois exécuté, ce code retournera bien le mot tous. Vous pouvez retrouver la position de départ de la correspondance la position terminale ainsi que les deux en même temps.
import re
chaine = "Bonjour tous le monde"
req = re.search(r"tous", chaine, re.I)
print(req.group())
print(req.start())
print(req.end())
print(req.span())
tous
8
11
(8,11)
Si vous souhaitez trouver toutes les correspondances sur l’expression régulière que vous souhaitez soumettre, vous devez utiliser findall(), car avec search(), la valeur de retour sera seulement la première occurrence.
import re
texte = """Vous êtes au numero 123
le suivant sera donc 124"""
regex = '\d+'
res = re.findall(regex, texte)
print(res)
['123','124']
Comme vous pouvez le constater, le résultat est donc les deux nombres présents dans la variable texte à savoir 123 et 124.
La fonction de remplacement d’une chaine de caractère
sub() qui vous permettra de remplacer la chaine de caractère initiale par un autre ou bien de supprimer certains éléments de cette chaine. Si nous revenons à notre exemple précédent :
import re
texte = """Vous êtes au numero 123
le suivant sera donc 124"""
regex = '\d+'
res = re.sub(r'\d',"",texte)
print(res)
‘Vous êtes au numero le suivant sera donc’
La méthode sub() a supprimer tous les chiffres présents dans la chaine de caractère contenue dans texte pour donner le résultat sur la dernière ligne.
On peut également rajouter l’argument cout=n pour spécifier le nombre d’occurrences sur lequel effectuer le remplacement, n étant le nombre d’occurrences. Donc en nous basant sur cela, si l’on souhaite récupérer seulement la première occurrence dans notre exemple précédent, nous aurons :
import re
texte = """Vous êtes au numero 123
le suivant sera donc 124"""
regex = '\d+'
res = re.sub(r'\d',"",texte, count=1)
print(res)
‘Vous êtes au numero le suivant sera donc 124’
Si vous souhaitez apprendre à faire d’autres manipulations, la documentation officielle de Python sur les expressions régulières vous donnera d’autres informations qui vous seront certainement utiles.
Un dernier argument peut être rajouté à la fonction sub() qui est un Flag. Cet argument servira à préciser le comportement de l’expression. Par exemple, si l’on souhaite que le remplacement se fasse sans se soucier de la casse, on peut l’écrire comme cela :
import re
texte = """Vous êtes au numero 123
le suivant sera donc 124"""
regex = '\d+'
res = re.sub(r'\d',"",texte, count=1, re.I)
print(res)
‘Vous êtes au numero le suivant sera donc 124’
Une autre fonction permet de remplacer une chaine de caractère par une autre : la fonction subn(). Elle exécute exactement les mêmes procédés que la fonction sub(), sauf qu’il renvoie également le nombre d’occurrences remplacé en plus de l’expression ayant subi la transformation. Donc, en utilisant cette fonction, cet exemple :
import re
texte = """Vous êtes au numero 123
le suivant sera donc 124"""
regex = '\d+'
res = re.subn(r'\d',"",texte)
print(res)
retournera (‘Vous êtes au numero le suivant sera donc’, 2).
La fonction group()
Nous avons déjà évoqué un peu plus haut cette fonction en disant qu’elle servait à récupérer l’ensemble des résultats de correspondances. Cependant, on peut également s’en servir pour diviser le résultat obtenu en plusieurs sous-groupes. Pour ce faire, il faut préciser le numéro du sous-groupe à retourner. Et pour obtenir tous les sous-groupes, il faut utiliser la fonction groups(). Regardons cela de plus près :
import re
m = re.match(r"(\d+)\.(\d+)", "123.456")
m.groups()
# resultat('123', '456')
m.group(1)
# resultat '123'
m.group(2)
# resultat '456'
Mise en pratique du regex en Python
Dans cette section, nous allons illustrer l’utilisation du regex en Python à travers deux exemples de cas d’utilisation les plus courants : la recherche et la validation d’adresse email et la validation d’un numéro de téléphone.
Rechercher et valider une adresse email
Le code qui suit permet d’effectuer la validation et la recherche d’une adresse email :
import re
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
def verif(email):
# pass the regular expression
# and the string in search() method
if(re.match(regex, email)):
print("Email valide")
else:
print("Email invalide")
email = "test@exemple.com"
verif(email)
# resultat : 'Email valide'
res = re.findall(regex, email)
print (res)
# resultat : 'test@exemple.com'
Ici, la variable regex spécifie notre expression régulière, à savoir qu’une adresse email peut contenir des caractères alphabétiques (en majuscule ou en minuscule) ou des caractères numériques ou encore des caractères spéciaux. Ces caractères doivent être suivis d’un « @ » puis d’une autre série de caractères avec les mêmes caractéristiques que les précédents. Enfin, l’adresse email doit être suivie d’un « . » et d’une chaine de caractère avec seulement des caractères alphabétiques.
Dans la fonction verif(email), on effectue cette vérification à l’aide de la fonction match(). Si la condition est vérifiée, on affiche que l’email est valide, sinon il ne l’est pas.
Pour retourner toutes les adresses email contenues dans la chaine, nous utilisons ici la fonction findall().
Validation de numéro de téléphone
Prenons le code suivant qui consiste à valider un numéro de téléphone français :
import re
numero = "+33 6 10 20 30 10"
regex = "(0|\\+33|0033)[1-9][0-9]{8}"
if re.match(regexp, numero) is not None :
print("Numero valide")
else:
print("Numero invalide")
#resultat : Numero valide
Dans cet exemple, notre expression régulière est construite de telle façon à ce que l’expression doit contenir un « 0 » ou un « +33 » ou encore un « 0033 ». Elle doit ensuite contenir un chiffre entre 1 et 9 suivi du reste du numéro, à savoir 8 chiffres compris entre 0 et 9. À l’aide de la fonction match(), nous vérifions si le numéro dans la variable numero correspond bien à cette expression. Le résultat est, comme vous le constatez oui.
Nous sommes arrivés au terme de cette chronique. Nous espérons que vous avez compris comment utiliser les expressions régulières pour extraire simplement des informations complexes d’une masse de données. Nous mettons à votre disposition une formation sur la programmation Scala de 1h pour que vous puissiez approfondir vos connaissances dans le Big Data ainsi que dans la programmation. Cliquez dans la boîte suivante pour le télécharger.