En chiffres romains, il y a sept caractères qui sont répétés et combinés de différentes manières pour représenter des nombres.
7.3.1. Rechercher les milliers
Qu’est-ce qui serait nécessaire pour vérifier qu’une chaîne de caractères quelconque constitue des chiffres romains valides
? Nous allons opérer caractère par caractère. Puisque les chiffres romains sont toujours écrits du plus grand vers le plus
petit, nous allons commencer par les plus grands : les milliers. Pour les nombres supérieurs à 1000, les milliers sont représentés
par une série de caractères M.
Exemple 7.3. Rechercher les milliers
>>> import re
>>> pattern = '^M?M?M?$'
>>> re.search(pattern, 'M')
<SRE_Match object at 0106FB58>
>>> re.search(pattern, 'MM')
<SRE_Match object at 0106C290>
>>> re.search(pattern, 'MMM')
<SRE_Match object at 0106AA38>
>>> re.search(pattern, 'MMMM')
>>> re.search(pattern, '')
<SRE_Match object at 0106F4A8>
|
Ce motif a trois parties :
- ^ - reconnaît ce qui suit uniquement
en début de chaîne. Si ce n’était pas spécfié, le motif
reconnaîtrait les M où qu’ils soient, ce
qui n’est pas ce que nous voulons. Nous voulons être sûrs que
les M, s’il y en a dans la chaîne, sont à
son début.
- M? - reconnaît un
M optionnel. Comme nous le répétons trois
fois, nous reconnaissons 0 à 3 M se
suivant.
- $ - reconnaît ce qui précède
uniquement à la fin de la chaîne. Lorsqu’il est combiné avec
^ en début de motif, cela signifie que le
motif doit correspondre à la chaîne entière, sans autres
caractères avant ou après les M.
|
|
L’essence du module re est la fonction
search, qui prend une expression régulière
(pattern) et une chaîne
('M') qu’elle va tenter de faire correspondre.
Si une correspondance est trouvée, search
retourne un objet ayant diverses méthodes permettant de décrire la
correspondance, sinon, search retourne
None, la valeur nulle de
Python. Tout ce qui nous
intéresse à ce stade est de savoir si le motif est reconnu, ce que
nous pouvons dire rien qu’en regardant la valeur retournée par
search. 'M' est reconnu
par cette expression régulière car le premier M
optionnel correspond et que le second et troisième
M sont ignorés.
|
|
'MM' est reconnu puisque les premier et
deuxième M optionnels correspondent et que le
troisième est ignoré.
|
|
'MMM' est reconnu puisque les trois
M correspondent.
|
|
'MMMM' n’est pas reconnu. Les trois
M correspondent, mais l’expression régulière
précise la fin de chaîne (par le caractère $)
et la chaîne ne s’arrête pas là (à cause du quatrième
M). Donc search retourne
None.
|
|
Un élément intéressant est qu’une chaîne vide est reconnue
par l’expression régulière, puisque tous les M
sont optionnels.
|
7.3.2. Rechercher les centaines
Les centaines présentent plus de difficultés que les milliers car
elles peuvent être exprimées de plusieurs manières mutuellement
exclusives, en fonction de leur valeur.
- 100 = C
- 200 = CC
- 300 = CCC
- 400 = CD
- 500 = D
- 600 = DC
- 700 = DCC
- 800 = DCCC
- 900 = CM
Il y a donc quatre motifs possibles :
- CM
- CD
- 0 à 3 C (0 si les centaines valent 0)
- D, suivi de 0 à 3 C
Les deux derniers motifs peuvent être combinés en :
- un D optionnel, suivi de 0 à 3
C
L’exemple suivant montre comment valider les centaines en chiffres romains.
Exemple 7.4. Rechercher les centaines
>>> import re
>>> pattern = '^M?M?M?(CM|CD|D?C?C?C?)$'
>>> re.search(pattern, 'MCM')
<SRE_Match object at 01070390>
>>> re.search(pattern, 'MD')
<SRE_Match object at 01073A50>
>>> re.search(pattern, 'MMMCCC')
<SRE_Match object at 010748A8>
>>> re.search(pattern, 'MCMC')
>>> re.search(pattern, '')
<SRE_Match object at 01071D98>
|
Ce motif commence de la même manière que le précédent, en
vérifiant le début de chaîne (^), puis les
milliers (M?M?M?). Ensuite vient la nouvelle
partie, entre parenthèses, qui définit un ensemble de trois motifs
mutuellement exclusifs séparés par des barres verticales :
CM, CD, and
D?C?C?C? (qui est un D
optionnel suivi de 0 à 3 C optionnels). Le
processeur d’expressions régulières teste chacun de ces motifs
dans l’ordre (de gauche à droite), prend le premier qui correspond
et ignore le reste.
|
|
'MCM' est reconnu car le premier
M correspond, que le second et troisième
M sont ignorés et que CM
correspond (et donc les motifs CD et
D?C?C?C? ne sont même pas examinés).
MCM est la représentation de
1900.
|
|
'MD' est reconnu car le premier
M correspond, les deuxième et troisième
M sont ignorés et que le motif
D?C?C?C? reconnaît D (chacun
des trois C est optionnel et est ignoré).
MD est la représentation de
1500.
|
|
'MMMCCC' est reconnu car les trois
M correspondent et que le motif
D?C?C?C? reconnaît CCC (le
D est optionnel et est ignoré).
MMMCCC est la représentation de
3300.
|
|
'MCMC' n’est pas reconnu. Le premier
M correspond, les deuxième et troisième
M sont ignorés et le CM
correspond, mais le $ ne correspond pas car
nous ne sommes pas encore à la fin de la chaîne (il nous reste le
caractère C à évaluer). Le C
ne correspond pas comme partie du motif
D?C?C?C? car le motif CM a
déja été reconnu et qu’ils sont mutuellement exclusifs.
|
|
Fait intéressant, une chaîne vide est toujours reconnue par
ce motif, car tous les M sont optionnels et
sont ignorés et que la chaîne vide est reconnue par le motif
D?C?C?C? dans lequel tous les caractères sont
optionnels et sont ignorés.
|
Ouf ! Vous voyez à quel point les expressions régulières peuvent
devenir compliquées ? Et nous n’avons vu que les milliers et les
centaines. Heureusement, si vous avez suivi
jusque là, les dizaines sont relativement simples puisqu’elles suivent
exactement le même motif. Mais continuons en examinant une autre manière d’exprimer ce motif.