from termcolor import cprint
from dateutil.tz import gettz
import datetime as dt
import locale
locale.setlocale(locale.LC_ALL, ('fr_FR', 'UTF-8'))
tzi = gettz('Europe/Brussels')
cprint('{} {}'.format('danielhagnoul', dt.datetime.now(tz=tzi).isoformat()), 'blue')
import re
obj_motif = re.compile(r'''
# code
# commentaire
''', re.VERBOSE | re.UNICODE)
Pour vos débuts, vous pouvez utiliser ce squelette de code tel quel, plus tard vous lirez avec attention les autres possibilités dans les documents en référence ci-dessous.
obj_motif = re.compile(r'''
(\d+)
# capture d'un groupe : ()
# groupe contenant un nombre constitué de chiffres [0-9] : \d
# nombre formé de 1 ou plusieurs chiffres : +
''', re.VERBOSE | re.UNICODE)
Pour nos essais de capture, nous utiliserons exclusivement la méthode finditer. Lorsque vous serez devenu un expert, vous découvrirez d'autres méthodes en lisant avec attention les documents en référence ci-dessous.
texte = '12 batteurs battant, 11 cornemuseurs, 10 seigneurs sautant, 126lapins'
iterator = obj_motif.finditer(texte)
for match in iterator:
print("group = {}, groups = {}, span = {}, start = {}, end = {}".format(
match.group(), match.groups(), match.span(), match.start(), match.end()))
obj_motif = re.compile(r'''
(\d+)\s
# capture d'un groupe : ()
# groupe contenant un nombre constitué de chiffres [0-9] : \d
# nombre formé de 1 ou plusieurs chiffres : +
# groupe suivi par un espace : \s
''', re.VERBOSE | re.UNICODE)
iterator = obj_motif.finditer(texte)
# 12 batteurs battant, 11 cornemuseurs, 10 seigneurs sautant, 126lapins
for match in iterator:
print("group = {}, groups = {}, span = {}, start = {}, end = {}".format(
match.group(), match.groups(), match.span(), match.start(), match.end()))
group() donne toujours le nombre inclus dans la capture (\d+) mais span() tient compte de l'espace
obj_motif = re.compile(r'''
(\w+|\d{2})
# le groupe de capture sélectionne
# un ou plusieurs caractères \w+
# ou |
# un nombre constitué de deux chiffres \d{2}
''', re.VERBOSE | re.UNICODE)
iterator = obj_motif.finditer(texte)
# 12 batteurs battant, 11 cornemuseurs, 10 seigneurs sautant, 126lapins
for match in iterator:
print("group = {}, groups = {}, span = {}, start = {}, end = {}".format(
match.group(), match.groups(), match.span(), match.start(), match.end()))
"126lapins" est capturé par \w+
obj_motif = re.compile(r'''
((\w+)\s|(\d{2})\s)
# capture contenant
# une capture d'un ou plusieurs caractères suivis par un espace (\w+)\s
# ou |
# une capture d'un nombre composé de deux chiffres et suivi par un espace (\d+)\s
''', re.VERBOSE | re.UNICODE)
iterator = obj_motif.finditer(texte)
# 12 batteurs battant, 11 cornemuseurs, 10 seigneurs sautant, 126lapins
for match in iterator:
print("group = {}, groups = {}, span = {}, start = {}, end = {}".format(
match.group(), match.groups(), match.span(), match.start(), match.end()))
groups() contient trois valeurs, un nombre ou des caractères suivis de un espace, un nombre ou des caractères sans espace, None pour le groupe n'ayant rien capturé.
Nous allons maintenant chercher uniquement des chiffres, mais dans un numéro de téléphone ce qui complique singulièrement la tâche.
Wikipédia nous donne la structure des numéros de téléphone en Belgique
Nota bene : lorsque vous construirez une expression rationnelle n'essayez pas de prendre en compte tous les errements que l'utilisateur pourrait commettre en tapant son texte. Je vous conseille d'être très directif. Vous devez obliger l'utilisateur à respecter des modèles précis, modèles que vous devez lui fournir en exemple.
obj_motif = re.compile(r'''
^ # la capture doit commencer au début du texte
(00\s{1}32\s{1}|\+32\s{1}|0)
# capture comprenant
# 00 32 un espace
# ou +32 un espace
# ou 0 sans espace
((\d{1})\s{1}(\d{3})|(\d{2})\s{1}(\d{2})|(\d{3}\s{1}\d{2}))
# capture comprenant
# un chiffre un espace trois chiffres
# ou 2 chiffres un espace deux chiffres
# ou 3 chiffres un espace deux chiffres
\s{1} # un espace
(\d{2}) # on capture deux chiffres
\s{1} # un espace
(\d{2}) # on capture deux chiffres
$ # la capture doit se terminer à la fin du texte
''', re.VERBOSE | re.UNICODE)
textes = [
'+32 4 125 56 78',
'+32 491 12 13 14',
'013 08 59 13',
'0451 12 13 14',
'00 32 451 12 13 14',
'0800 01 02 03',
'0900 03 04 05',
'070 99 98 97',
'078 11 44 99',
]
for texte in textes:
iterator = obj_motif.finditer(texte)
for match in iterator:
print("group = {}, groups = {}, span = {}, start = {}, end = {}".format(
match.group(), match.groups(), match.span(), match.start(), match.end()))
from collections import Counter
""" Nota bene
import locale
locale.setlocale(locale.LC_ALL, ('fr_FR', 'UTF-8'))
sont déclarés au début de ce documen.
"""
texte = '''
C'est l'évadé, du Névada.
Qui s'évada dans, la vallée
Dans la vallée, du Névada ?
Qu'il dévala, pour s'évader
Sur un vilain vélo volé !
Qu'il a volé, dans une villa
Et le valet, qui fut volé.
Vit l'évadé, qui s'envola
'''
obj_motif = re.compile(r'''
(\w+)
''', re.VERBOSE | re.UNICODE)
# Capture des mots, le texte étant mit en minuscules au préalable
iterator = obj_motif.finditer(texte.lower())
# Exploiter l'iterator en construisant une liste triée avec les groupes capturés
lst = sorted([match.group() for match in iterator if len(
match.group()) > 2], key=locale.strxfrm)
print('Nombre de mots = {}'.format(len(lst)))
# Construire un dictionnaire mot: fréquence
cnt = Counter(lst)
# Imprimer le contenu du dictionnaire
for key, value in cnt.items():
print('Mot : {}, fréquence : {}'.format(key, value))
obj_motif = re.compile(r'''
# (?:(A)\w+) signifie capture le reste des caractères
# s'il commence par le contenu de A, lequel
# est capturé en premier.
(?:([a-z]{0,}[\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]{1})\w{0,})
# A contient
# la capture de zéro ou plusieurs lettres de a à z
# la capture d'un caractère accentué FR
''', re.VERBOSE | re.UNICODE)
iterator = obj_motif.finditer(texte.lower())
lst = sorted([match.group() for match in iterator if len(
match.group()) > 2], key=locale.strxfrm)
print('Nombre de mots = {}'.format(len(lst)))
cnt = Counter(lst)
for key, value in cnt.items():
print('Mot : {}, fréquence : {}'.format(key, value))
obj_motif = re.compile(r'''
(\w+(?=,))
# capture uniquement les caractères suivis par une virgule
''', re.VERBOSE | re.UNICODE)
iterator = obj_motif.finditer(texte.lower())
lst = sorted([match.group() for match in iterator if len(
match.group()) > 2], key=locale.strxfrm)
print('Nombre de mots = {}'.format(len(lst)))
cnt = Counter(lst)
for key, value in cnt.items():
print('Mot : {}, fréquence : {}'.format(key, value))
Cette introduction se termine alors que nous avons seulement découvert quelques-unes des possibilités des expressions rationnelles en Python. Je pense que si vous vous appropriez son contenu en faisant quelques exercices vous aurez beaucoup moins de mal à comprendre le contenu des liens ci-dessous.
!jupyter nbconvert --to html exp_reg.ipynb