Jul 03, 2024

Wiki

Python

Aide

edit SideBar

Search

Deuxieme Exemple


Voici un deuxième exemple d'utilisation d'expressions rationnelles, toujours tiré de dive into Python.

Les sept caractères romains

Les caractères romains sont au nombre de sept :

  • I = 1
  • V = 5
  • X = 10
  • L = 50
  • C = 100
  • D = 500
  • M = 1000

Quatre caractères commencent par 1 en écriture décimale (I, X, C et M), les trois autres par 5.

Les chiffres romains

Les caractères romains servent à construire les chiffres romains, à partir des règles suivantes :

  • Les caractères sont additifs :
    • I est 1, II est 2 et III est 3.
    • VI est 6 (littéralement «5 et 1»), VII est 7 et VIII est 8.
    • etc.
  • Les chiffres en 1 se répètent au plus trois fois. Au lieu de les répéter 4 fois, on réalise une soustraction du prochain chiffre en 5. Ainsi,
    • on n'écrit pas IIII, mais IV,
    • 40 s'écrit XL («10 de moins que 50»),
    • 43 s'écrit XLIII quand 44 se note XLIV.
  • De la même manière,
    • si 8 s'écrit VIII, 9 se note IX.
    • 90 se note XC, quand 900 s'écrit CM.
    • etc.
  • Les caractères commençant par 5 ne peuvent être répétés :
    • 10 est toujours représenté par X, jamais par VV.
    • 100 s'écrit C, jamais LL.

Rechercher les milliers

Le motif des milliers

On souhaite vérifier qu’une chaîne de caractères correspond à un chiffre romain.

On commence par vérifier que l'utilisation du caractère des milliers M est valide, vu que les caractères romains s'utilisent du plus grand vers le plus petit :

  >>> import re
  >>> motif = '^M?M?M?$'

Le motif précédent a trois parties :

  • ^ reconnaît ce qui suit uniquement en début de chaîne : les M, s’il y en a, sont au début.
  • M? reconnaît 0 ou 1 M. Comme M? est répété trois fois, 0 à 3 M se suivant seront reconnus.
  • \$ reconnaît ce qui précède uniquement à la fin de la chaîne. Couplé avec ^ (en début de motif) signifie que le motif doit correspondre à la chaîne entière, sans autres caractères avant ou après les M.

Exemples d'utilisation

search est la fonction de base du module re. Elle reçoit une expression régulière (un motif), et une chaîne de caractères.

Si la chaîne contient le motif, un objet SRE_Match est renvoyé, signalant que l'expression régulière est présente. Sinon, search ne renvoie rien...

  >>> re.search(motif, '')
  <SRE_Match object at 0106F4A8>
  >>> re.search(motif, 'M')
  <SRE_Match object at 0106FB58>
  >>> re.search(motif, 'MM')
  <SRE_Match object at 0106C290>
  >>> re.search(motif, 'MMM')
  <SRE_Match object at 0106AA38>
  >>> re.search(motif, 'MMMM')

Les quatre premières chaînes sont reconnues, qui correspondent à 0, 1, 2 ou trois utilisation du caractère des milliers M. La dernière chaîne ne l'est pas : 4 M n'est pas acceptable

Nous verrons plus loin que, en cas de présence du motif, l'objet SRE_Match permettra de décrire précisément la correspondance.

Rechercher les centaines

Étude

Il est plus délicat d'exprimer le motif des centaines, vu que C n'est pas l'unique caractère utilisé :

  • 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.

Qui peuvent se condenser en :

  • CM,
  • CD,
  • un D optionnel, suivi de 0 à 3 C

Réalisation du motif

Le motif correspondant aux milliers et centaines est donc le suivant :

  >>> import re
  >>> pattern = '^M?M?M?(CM|CD|D?C?C?C?)$'

Il utilise le tube | pour signifier «ou».

Exemples d'utilisation

Vérifions que les motifs, sensés être reconnus, le sont bien...

  >>> 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>

Travaux pratiques

Prendre en charge les dizaines.

Utilisation de la syntaxe {n,m}

Plutôt que de multiplier les ?, on peut utiliser la syntaxe {m,n}, qui signifie «de m à n fois le caractère précédent» :

  >>> motif = '^M{0,3}$'
  >>> re.search(motif, 'M')
  <_sre.SRE_Match object at 0x008EEB48>
  >>> re.search(motif, 'MM')
  <_sre.SRE_Match object at 0x008EE090>
  >>> re.search(motif, 'MMM')
  <_sre.SRE_Match object at 0x008EEDA8>
  >>> re.search(motif, 'MMMM')

Tout se passe sans problème.

Notons que la syntaxe {m} signifie exactement m fois le motif précédent.

Rechercher les dizaines

La recherche

On souhaite dorénavant étendre notre expression rationnelle, pour prendre en compte les dizaines.

Cela se fait comme pour les centaines :

  >>> motif = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})$'
  >>> re.search(motif, 'MCMXL')
  <_sre.SRE_Match object at 0x008EEB48>
  >>> re.search(motif, 'MCML')
  <_sre.SRE_Match object at 0x008EEB48>
  >>> re.search(motif, 'MCMLX')
  <_sre.SRE_Match object at 0x008EEB48>
  >>> re.search(motif, 'MCMLXXX')
  <_sre.SRE_Match object at 0x008EEB48>
  >>> re.search(motif, 'MCMLXXXX')
  >>>

Travaux pratiques

Finir le motif, pour prendre en charge les unités (correction).

Page Actions

Recent Changes

Group & Page

Back Links