Une expression régulière à traduire

Bonjour,

Dans un code Python, je retrouve deux expressions régulières que je n’arrive pas à expliquer dans le détail.
Je sais ce que fait ce bout de code mais je ne parviens pas à comprendre la signification de chaque élément des deux expressions régulières.

Ce code est une extension pour Inkscape.

[code]

Cette extension ferme le chemin en ajoutant un ‘z’ avant chaque ‘m’

s’il n’est pas le premier ‘m’ et s’il n’est déjà pas précédé d’un ‘z’.

import inkex, re, simplepath

class CloseCurves(inkex.Effect):
def init(self):
inkex.Effect.init(self)
def effect(self):
for id, node in self.selected.iteritems():
if node.tag == inkex.addNS(‘path’,‘svg’):
d = node.get(‘d’)
d = simplepath.formatPath( simplepath.parsePath(d) )
d = re.sub(r’(?i)(m[^mz]+)’,r’\1 Z ‘,d) <===== a
d = re.sub(r’(?i)\sz\sz\s*’,r’ Z ',d) <===== b
node.set(‘d’, d)

e = CloseCurves()
e.affect()[/code]

Dans Inkscape, un tracé ouvert est un code XML comme ceci :

m 462.85714,823.79075 128.57143,-111.42857 -2.85714,134.28572 -120,108.57143 c 0,0 -65.71429,-17.14286 -17.14286,-97.14286

Le même tracé qui a été fermé est un code XML comme ceci :

m 591.42857,712.36218 -2.85714,134.28572 -120,108.57143 c 0,0 -65.71429,-17.14286 -11.42857,-114.28572 z

Ce tracé d’exemple comporte 3 premiers segments de droite successifs et une courbe de Bézier pour former un seul tracé ouvert.
La fermeture s’effectue avec le point de départ du premier segment de droite et le dernier point de la courbe de Bézier.
La petite différence entre les coordonnées des premier et dernier point provient du fait que Inkscape a déterminé la position du point “de fermeture” au milieu de la distance qui séparait les deux points terminaux du tracé de départ.

On s’aperçoit rapidement qu’une lettre ‘z’ a été ajoutée en fin de définition XML du tracé quand je ferme le tracé initial.

Les deux expressions sont indiquées dans le code par <=====.

Qui peut m’aider à les comprendre ?
Merci.

d = node.get('d') d = simplepath.formatPath( simplepath.parsePath(d) ) d = re.sub(r'(?i)(m[^mz]+)',r'\1 Z ',d) <===== a d = re.sub(r'(?i)\s*z\s*z\s*',r' Z ',d) <===== b node.set('d', d)

Je ne suis pas un expert en regex Python, en voici ma lecture :
motif a – «’(?i)(m[^mz]+)’», «(?i)» = ignore la casse, dans ce contexte «(m[^mz]+)» = tout ce qui suit un m ou un M jusqu’au prochain m M z ou Z
substitution a – «’\1 Z ‘», ajoute un « Z » le groupe «(m[^mz]+)» identifié (les groupes ?)
motif b – «’(?i)\sz\sz\s*’», en ignorant la casse, repère toutes les suites de z Z quelque soit le nombre d’espace les séparant
substitution b – ’ Z ’ remplace les suite de séparateurs z et Z par un unique Z précédé et suivi d’un unique espace

la ligne a semble ajouter un «z» après chaque groupe commençant par «m», et cloturé par un «m» ou un «z». La ligne b remplace deux «z» consécutif par un seul en mettant les espaces « au carré », pour ainsi dire. Une bonne manip en deux temps pour obtenir le résultat escompté, décrit en en-tête de la portion de code que tu as fournie.

Les questions que je me pose sont :
— pourquoi ces grands Z semblent ressortir en petits z dans l’exemple que tu donnes ? Est-ce le comportement de Python en mode “ignore case” ?
— les regex s’appliquent-elles autant de fois que possible par défaut en Python ? (je pense au modificateur “g” en perl… en perl par défaut seul le premier motif d’une ligne est substitué, le modificateur “g” répète la substitution de motif autant de fois que possible sur une ligne)

Ces comportements peuvent s’expliquer par des comportements spécifiques à Python.

Je déplace dans "programmation"
Ce fil n’a pas sa place dans PC.

[quote=“ricardo”]Je déplace dans "programmation"
Ce fil n’a pas sa place dans PC.[/quote]
Oups ! Désolé :blush: La distraction du week-end.

[quote=“bobo38”]

(1) la ligne a semble ajouter un «z» après chaque groupe commençant par «m», et cloturé par un «m» ou un «z».
(2) La ligne b remplace deux «z» consécutif par un seul en mettant les espaces « au carré », pour ainsi dire. Une bonne manip en deux temps pour obtenir le résultat escompté, décrit en en-tête de la portion de code que tu as fournie.

Les questions que je me pose sont :
(3) — pourquoi ces grands Z semblent ressortir en petits z dans l’exemple que tu donnes ? Est-ce le comportement de Python en mode “ignore case” ?
(4) — les regex s’appliquent-elles autant de fois que possible par défaut en Python ? (je pense au modificateur “g” en perl… en perl par défaut seul le premier motif d’une ligne est substitué, le modificateur “g” répète la substitution de motif autant de fois que possible sur une ligne)

Ces comportements peuvent s’expliquer par des comportements spécifiques à Python.[/quote]
(1) : en effet, le simple fait d’ajouter un z en fin de “groupe”, c’est-à-dire à la fin de la description en XML du tracé (chemin dans Inkscape) provoque la fermeture du tracé (chemin). Je viens de tester la chose manuellement via l’éditeur XML dans Inkscape pour m’assurer que cela fonction aussi.
Un chemin dessiné dans Inkscape commence toujours par un m qui indique, si je ne me trompe, que le point de départ du tracé n’est pas sur l’origine 0,0 de la page mais qu’il a été déplacé (move) à une coordonnée précise (en pixels dans Inkscape).

(2) : En agissant ainsi en première ligne, on risque de se retrouver avec un chemin déjà fermé (on lance cette extension après avoir sélectionné un(des) chemin dans la fenêtre de dessin dans Inkscape. Un carré déjà fermé est aussi un chemin.) et comme cette expression place systématiquement un z en en fin (avec un espace avant et après comme cela est exigé dans l’éditeur XML de Inkscape), ce carré sera décrit dans l’éditeur XML risque d’être décrit avec 2 z terminaux.
Cette seconde ligne supprime ce z surnuméraire.
Mais je me demande si cette ligne est nécessaire. Quand je modifie manuellement le code XML du chemin en lui appliquant 2 z, dès que je valide, le z surnuméraire est automatiquement effacé. Une autocorrection qui a probablement été intégrée à l’éditeur.

(3) : Dans l’éditeur XML dans Inkscape, les commandes sont en minuscules. Il n’y a pas de grand Z. Là encore, l’éditeur XML dans Inkscape modifie automatiquement un Z en z pour que cela corresponde à une écriture correcte de la description du chemin fermé.

(4) : Oups ! Mais cela dépasse, et de loin, mes compétences.

Merci pour ton analyse de l’expression qui m’est très précieuse. Les expressions régulières, ce n’est vraiment pas “très compréhensible” pour un néophyte :017 .

A+

Edit :
Grâce à ton aide, j’ai décortiqué les deux expressions régulières et mes cogitations ont donné ceci :

J’espère que c’est correct :dance: … rassurez-moi :wink:
Le rétro-ingénierie n’est vraiment pas une sinécure :open_mouth:

A+