Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Expression reguliere (w*){1,2}

6 réponses
Avatar
G. Vidon
Bonjour,
Je voulais récupèrer 3 éléments hexa dans une chaine de caractères
Pour faire plus élégant que ([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F]),
j'ai essayé ([0-9a-fA-F]){3}. C'est décevant, je ne récupère que le
dernier élément.
Comment pourrais-je faire de façon élégante ce genre d'extraction.
Est-il possible d'avoir une façon élégante de faire ([0-9a-fA-F]){1,2}
sans devoir faire de traitements conditionnelles pour connaitre la forme
de la chaine de caractères.

Merci :)

Guillaume

6 réponses

Avatar
tiissa
G. Vidon > wrote:
Pour faire plus élégant que ([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F]),
j'ai essayé ([0-9a-fA-F]){3}. C'est décevant, je ne récupère que le
dernier élément.


Pas forcément mieux, mais j'essaierais plutôt de récupérer l'ensemble
des 3 groupes : "([0-9a-fA-F]{3})".

Est-il possible d'avoir une façon élégante de faire ([0-9a-fA-F]){1,2}
sans devoir faire de traitements conditionnelles pour connaitre la forme
de la chaine de caractères.


Avec la méthode d'au dessus je pense que ce n'est plus un problème.

Avatar
G. Vidon
tiissa wrote:
G. Vidon > wrote:

Pour faire plus élégant que ([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F]),
j'ai essayé ([0-9a-fA-F]){3}. C'est décevant, je ne récupère que le
dernier élément.



Pas forcément mieux, mais j'essaierais plutôt de récupérer l'ensemble
des 3 groupes : "([0-9a-fA-F]{3})".

Il faut ensuite séparer les sous-ensembles. J'avais pensé à cette

solution mais je ne trouve pas cela assez élégant :-)
Ce qui serait super, c'est que l'on puisse obtenir des items nommés. Du
genre
(?P<item*>regex){2,5}
Et on obtient, item1 item2 ... itemn ou un tuple ( <item1>, ...)

Mais là je rêve :)
Guillaume


Avatar
tiissa
G. Vidon > wrote:
tiissa wrote:

Pas forcément mieux, mais j'essaierais plutôt de récupérer l'ensemble
des 3 groupes : "([0-9a-fA-F]{3})".


Il faut ensuite séparer les sous-ensembles. J'avais pensé à cette
solution mais je ne trouve pas cela assez élégant :-)


Dans ce cas précis, où il ne s'agit que d'un caractère à chaque fois, ce
n'est pas très difficile : list(m.groups()[0]).

Si le nombre de caractère est fixe, on s'en sort aussi facilement (avec
un itérateur par exemple).


Ce qui serait super, c'est que l'on puisse obtenir des items nommés. Du
genre
(?P<item*>regex){2,5}
Et on obtient, item1 item2 ... itemn ou un tuple ( <item1>, ...)


Il y a moyen de le faire soi-même.
Une première méthode, dans le cas où le nombre d'itération est borné,
est de générer l'expression régulière avec la liste des noms. Facile,
pas cher.

Sinon, il suffit de faire une boucle en en matchant une à chaque fois et
de remplir le dictionnaire avec les noms génériques. Là non plus ça
n'est pas très compliqué, mais il faut faire en deux temps dans le cas
où l'expression régulière est plus compliquée.


Au final, il y a bien des solutions pratiques mais le critère d'élégance
est parfois plus difficile à remplir. ;)


Avatar
Guillaume Vidon
G. Vidon > wrote:

tiissa wrote:

Pas forcément mieux, mais j'essaierais plutôt de récupérer l'ensemble
des 3 groupes : "([0-9a-fA-F]{3})".



Il faut ensuite séparer les sous-ensembles. J'avais pensé à cette
solution mais je ne trouve pas cela assez élégant :-)



Dans ce cas précis, où il ne s'agit que d'un caractère à chaque fois, ce
n'est pas très difficile : list(m.groups()[0]).

En fait, ce genre de solutions ne m'interesse pas car j'ai déjà

rencontré plusieurs fois ce problème et je voudrais avoir une solution
générique et ... élégante :)
Si le nombre de caractère est fixe, on s'en sort aussi facilement (avec
un itérateur par exemple).


Ce qui serait super, c'est que l'on puisse obtenir des items nommés. Du
genre
(?P<item*>regex){2,5}
Et on obtient, item1 item2 ... itemn ou un tuple ( <item1>, ...)



Il y a moyen de le faire soi-même.
Une première méthode, dans le cas où le nombre d'itération est borné,
est de générer l'expression régulière avec la liste des noms. Facile,
pas cher.

Sinon, il suffit de faire une boucle en en matchant une à chaque fois et
de remplir le dictionnaire avec les noms génériques. Là non plus ça
n'est pas très compliqué, mais il faut faire en deux temps dans le cas
où l'expression régulière est plus compliquée.


Au final, il y a bien des solutions pratiques mais le critère d'élégance
est parfois plus difficile à remplir. ;)
Ton idée de générer dynamiquement l'expression rationnelle me plait

bien. Je pense faire ainsi :
On implante une nouvelle classe d'objets Match qui acceptent des
expressions régulières de la forme que j'ai décrite au dessus.
On analyse (parse) l'expression rationnelle une première fois
on remplace (?P<item*>regexp){n,m} par (?P<item>regexp{n,m})
On reanalyse
Pour chaque item obtenu, on parse ^(regexp).* -> séparation des items ->
création du dictionnaire des items item1 ...
Si itemn a plusieurs définitions, j'hésite entre garder la dernière
définition ou renvoyer une exception de collision.
Guillaume



Avatar
tiissa
Guillaume Vidon > wrote:

Sinon, il suffit de faire une boucle en en matchant une à chaque fois et
de remplir le dictionnaire avec les noms génériques. Là non plus ça
n'est pas très compliqué, mais il faut faire en deux temps dans le cas
où l'expression régulière est plus compliquée.


On implante une nouvelle classe d'objets Match qui acceptent des
expressions régulières de la forme que j'ai décrite au dessus.
On analyse (parse) l'expression rationnelle une première fois
on remplace (?P<item*>regexp){n,m} par (?P<item>regexp{n,m})
On reanalyse
Pour chaque item obtenu, on parse ^(regexp).* -> séparation des items ->
création du dictionnaire des items item1 ...


Voilà, c'est exactement ce que je disais, la séparation des items étant
réalisée un par un dans une boucle.

Si itemn a plusieurs définitions, j'hésite entre garder la dernière
définition ou renvoyer une exception de collision.


Là par contre, je n'ai pas compris.
S'il a matché au premier passage (regexp*), tu pourras toujours lui
faire matcher (regexp)(regexp)...(regexp) en le faisant un par un avec
(regexp)(regexp*) tant que la chaîne n'est pas vide, non ?


Avatar
Guillaume Vidon
Si itemn a plusieurs définitions, j'hésite entre garder la dernière
définition ou renvoyer une exception de collision.



Là par contre, je n'ai pas compris.
S'il a matché au premier passage (regexp*), tu pourras toujours lui
faire matcher (regexp)(regexp)...(regexp) en le faisant un par un avec
(regexp)(regexp*) tant que la chaîne n'est pas vide, non ?


Je parle d'un cas trés limite où l'on a collision de noms de variables :
item* est défini plusieurs fois
item1* et item* avec nombre d'éléments > 10 -> collision de nom :)

Ca n'a pas beaucoup d'importance :)
Merci