Voulant me lancer dans les regexp pour faciliter certains bouts de code, je bute déjà. J'ai une string issue d'un CSV, et je voudrai remplacer un élément de cette string, sans passer par un split sur le ';'.
Voici un exemple du string et de la reg exp que j'utilise :
$data = "02-LOGS;13/04/2015 18:17:59;USA6M1;MMS"
StringRegExp($data, "^[^;]*;[^;]*;([^;]*);[^;]*", 1) ; me renvoie bien ce que je cherche : "USA6M1"
StringRegExpReplace($data, "^[^;]*;[^;]*;([^;]*);[^;]*", "DD") ; je m'attendrai à avoir "02-LOGS;13/04/2015 18:17:59;DD;MMS" mais j'ai "DD"
Ça doit être tout bête, mais je ne trouve pas comment faire pour remplacer uniquement le USA6M1 trouvé et non pas toute la chaine.
Modifié en dernier par Clampu le ven. 17 avr. 2015 11:32, modifié 1 fois.
Yeah super. J'ai dû un peu creuser pour comprendre (notamment le "(?U)" et le "(?=" que je ne connaissait pas, tu peux d'ailleurs m'en dire un peu plus ?), et ça m'a bien aidé.
Pour l'exercice, en respectant ma logique (moins correcte que la tienne), pour faire fonctionner ma regexp :
C'est exactement ce que j'avais fait ! sauf que d'après ce site, j'ai 2 résultats (un en rouge un en vert) ce qui me laissait penser que ce n'était pas possible, je n'ai donc même pas tenté avec autoit dommage j'aurai perdu moins de temps.
Peux tu m'expliquer pourquoi il remplace le contenu de la seconde parenthèse et pas la première ? Je dois avoir mal compris le principe des parenthèses.
Les parenthèses sont des groupes capturants, qui peuvent être réutilisés plus loin dans l'expression et/ou lors d'un remplacement avec StringRegExpReplace (back-reference)
Dans mon exemple, j'ai utilisé deux groupes capturants auxquels je ne fais aucune référence - ni dans l'expression, ni dans le remplacement.
Le premier groupe sert juste à appliquer le {2} à ce groupe. Quant au deuxième, il ne sert strictement à rien (je sais pas pourquoi j'ai mis un groupe là...
Maintenant pour revenir au pourquoi du remplacement, il faut comprendre qu'un remplacement par regex n'opére que sur la partie concernée, parenthèses ou non.
Les parenthèses sont juste des groupes qui servent à matcher une chaîne, rien de plus.
Si je fais StringRegExpReplace("abcde", "abc", "") ou StringRegExpReplace("abcde", "a(b)c", ""), j'ai le même résulat, puisque le remplacement s'effectue sur l'ensemble de l'expression (la partie concernée est abc)
Le \K est justement là pour dire que la partie précédemment matchée n'est pas concernée par le remplacement.
Donc su je fais StringRegExpReplace("abcde", "ab\Kc", ""), seul le "c" sera remplacé, de même avec l'expression StringRegExpReplace("abcde", "a(b)\Kc", "") dans laquelle la capture ne sert à rien.
Si on n'avait pas utilisé le \K, on aurait pu faire un truc du genre StringRegExpReplaceabcde, "(.+)c", "$1") : ici le remplacement opéré sur toute la chaîne "abc".
Le groupe (ab) est capturé dans l'expression et on le réutilise pour le remplacement : ce qui revient à dire :
- j'effectue un remplacement sur :
n'importe quel caractère jusqu'à la lettre "c" (je capture le tout)
suivit de "c"
=> l'expression matche (ab)c
- je remplace (ab)c par $1 ($1 étant le groupe capturé (ab) )
Pour appliquer ça à l'expression d'origine, on aurait pu faire un truc du genre StringRegExpReplace($data, "^((?:[^;]*;){2})[^;]*", "$1DD")
Ici, le remplacement s'effectue sur 02-LOGS;13/04/2015 18:17:59;USA6M1 (seulement la partie qui match l'expression, la partie de droite n'est pas concernée)
On capture donc le groupe (02-LOGS;13/04/2015 18:17:59;) en $1 et on remplace tout (02-LOGS;13/04/2015 18:17:59;)USA6M1 par $1DD
J'espère avoir été suffisamment clair dans ces explications, désolé si si ça t'embrouille...
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
Sur regex101.com t'as des explications sur l'expression (pour savoir à quoi sert (?U) par exemple). (?U).*; est pareil que .*?;
Ta logique n'était pas mauvaise. Et je crois d'ailleurs que l'utilisation de [^;]* serait meilleure car ça évite des retours sur trace. Il y a les parties Laziness Instead of Greediness et An Alternative to Laziness de cette page http://www.regular-expressions.info/repeat.html qui en parlent. Tu peux aussi utiliser le "regex debugger" de regex101 pour voir le nombre d'étapes qu'il faut pour terminer ; mais ça peut aussi être utile pour comprendre ce qui ne va pas.
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)