1

Bonjour à tous smile

J'ai actuellement une fonction qui fait plusieurs lignes que j'aimerais simplifier en utilisant une ou plusieurs expressions régulières.

La finalité de cette fonction est de donner la masse molaire d'une molécule en ne connaissant que sa formule (par exemple Hf(SO4)2)et les masse molaires des élements la constituants.
Les élément commençant par une majuscule, et les parenthèses permettent de donner un indice à un ensemble d’éléments.
Ce qui me pose problème c'est de séparer chaque élément et de les lier avec leur indice respectif.
Parfois il n'y a pas d'indice après les parenthèses : cela correspond à un indice 1.

Idéalement j'obiens un tableau à deux dimensions : l'élement et son indice.
Par exemple pour Hf(SO4)2 ===> myArray = { [HF,1],[S,2],[O,8] }

Les - ou -2 (- ou + avec un chiffre après, ou pas) à la fin représente la charge, et ne sont pas à traiter. Dans ma fonction je fais un substring des le début pour le virrer afin de ne plus m'encombrer avec.
Voici quelques formules pour l'exemple :
Hg(SeCn)4-2 => Hg(SeCn)4 si on virre la charge dès le départ.
Hg(SeCn)3- => Hg(SeCn)3 si on virre la charge dès le départ.
Am(H2PO4)+2 => Am(H2PO4) si on virre la charge dès le départ.

Le mieux que j'obtiens c'est : myRegex = New Regex("[(\)d+]") qui ne me permet pas de propager l'indice aux élements entre parentheses.
Je suis un peu nul avec les expressions régulières, et je ne sais pas trop comment placer les crochets et parenthèses pour obtenir des tableaux utilisables... sad

Est ce que quelqu'un a une idée ?
Est-il possible d'obtenir un tableaux à deux dimensions avec un regex.split() ?

Merci d'avance smile

2

Si les parenthèses sont récursives, tu ne vas pas pouvoir le faire avec des expressions régulières (sauf si la méthode que tu utilises autorise (?x) ou (?R))...
avatar

3

hélas en effet, une expression régulière déteste la récursivité.

il te faut travailler avec une pile pour te souvenir de toutes les parenthèses déja ouvertes.

4

Merci de vos réponses.
Étrangement, les parenthèses ne sont pas récursives. "Étrangement" car il me semble que rien ne l'interdit, mais je viens de vérifier dans ma liste d'espèces et il n'y en a pas.

En revanche je peux avoir plusieurs fois le même élément, par exemple :
Gd(CH3CH2CH2CH2CO2)2+
Ce qui ne devrait pas poser de problème même si le regex ne le gère pas : Je pourrais vérifier si il y a des éléments déjà présent dans mon tableau et additionner les indices.

5

Peut-il y avoir d'autres éléments après les parenthèses ?
Si oui, en premier, tu peux faire ceci :
([^(]*)\((.*)\)(\d?)(.*)Qui retourne 4 parties de l'expression :
- Tout ce qui se trouve avant les parenthèses.
- Tout ce qui se trouve entre les parenthèses.
- Le coefficient des parenthèses.
- Tout ce qui se trouve après les parenthèses.

S'il n'y a jamais rien après les parenthèses, tu peux retirer la dernière partie :
([^(]*)\((.*)\)(\d?)

Après, il ne te reste plus qu'à trouver la liste des éléments avec :
([A-Z][a-z]*)(\d?)que tu appliques sur la première, la deuxième et la quatrième partie retournée par l'expression précédente.

Il ne te reste plus qu'à multiplier les coefficients trouvés pour les éléments de la seconde partie par le coefficient des parenthèses donné par la première expression smile
avatar

6

Excellent, merci.
Je viens de tester ta première expression et ça semble très bien. Quand je vois la syntaxe de ton expression, je vois je n'y étais pas du tout.
Pour info, il peux y avoir d'autres éléments après les parenthèses.
J'implémente ça, ainsi que ton expression qui retourne la liste des éléments et je reviens te dire si ça marche.
Merci encore.

7

Aïe, ça bug lorsque il y a plusieurs parenthèses, par exemple avec Cr(OH)4(HPO4)(H2PO4)
J'essais de voir d'ou ça viens.
Je me demande pourquoi il y a parfois des éléments vides dans le tableau après un split ?

8

En effet, je n'ai pas prévu qu'il puisse y avoir plusieurs parenthèses tongue
Pour que ça fonctionne, il faut utiliser cette expression :
([^(]*)\(([^)]*)\)(\d?)
Il faudra utiliser la seconde expression sur les différents résultats retournés.

Si certaines parties sont vides, c'est qu'il n'y a rien dedans cheeky
Pour les parties devant contenir des éléments, c'est qu'il n'y en a pas. Pour les autres, ce sont des coefficients à 1.
avatar