[R] RegExpReplace sur du CSV

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Clampu
Niveau 3
Niveau 3
Messages : 48
Enregistré le : mer. 16 mai 2012 22:08
Status : Hors ligne

[R] RegExpReplace sur du CSV

#1

Message par Clampu »

Bonjour :D ,

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 :

Code : Tout sélectionner

$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.
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2273
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] RegExpReplace sur du CSV

#2

Message par jchd »

Comme ça ?

Code : Tout sélectionner

Local $data = "02-LOGS;13/04/2015 18:17:59;USA6M1;MMS"
Local $data1 = StringRegExpReplace($data, "(?U)^.*;.*;\K(.*(?=;.*$))", "DD")
ConsoleWrite($data1 & @LF)
 
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Clampu
Niveau 3
Niveau 3
Messages : 48
Enregistré le : mer. 16 mai 2012 22:08
Status : Hors ligne

Re: [..] RegExpReplace sur du CSV

#3

Message par Clampu »

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 :

Code : Tout sélectionner

StringRegExpReplace($data, "^[^;]*;[^;]*;\K([^;]*)(?=;[^;]*)", "DD")
et j'ai pu comprendre pourquoi la mienne était KO. Merci !
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2511
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: [R] RegExpReplace sur du CSV

#4

Message par jguinch »

Un poil raccourci :

Code : Tout sélectionner

StringRegExpReplace($data, "^([^;]*;){2}\K([^;]*)", "DD")
 
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
Clampu
Niveau 3
Niveau 3
Messages : 48
Enregistré le : mer. 16 mai 2012 22:08
Status : Hors ligne

Re: [R] RegExpReplace sur du CSV

#5

Message par Clampu »

C'est exactement ce que j'avais fait :lol: ! 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.
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2511
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: [R] RegExpReplace sur du CSV

#6

Message par jguinch »

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 !
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R] RegExpReplace sur du CSV

#7

Message par mikell »

Tidiou
C'est pas un message c'est un tutoriel, et très clair en plus (à la 3ème lecture) :mrgreen:

Un peu méconnu mais très pratique le \K ("oublie ce qui précède")

Code : Tout sélectionner

Msgbox(0,"", StringRegExpReplace("abcde-abcde-abcde", ".+\Kabc", "X-") )

Code : Tout sélectionner

Local $data = "02-LOGS;13/04/2015 18:17:59;USA6M1;MMS"
Local $data1 = StringRegExpReplace($data, ".+;\K[^;]*(?=;)", "DD")
Msgbox(0,"", $data1)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [R] RegExpReplace sur du CSV

#8

Message par orax »

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)
Répondre