[R] Suppression puis ajout dans un tableau

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
clark17
Niveau 4
Niveau 4
Messages : 70
Enregistré le : ven. 23 sept. 2011 02:12
Status : Hors ligne

[R] Suppression puis ajout dans un tableau

#1

Message par clark17 »

Bonjour à tous,

Je fais face à un petit problème dont je ne trouve pas la solution.
J'ai un petit tableau qui contient différentes variables. Je souhaite substituer une plage du tableau (entre les valeurs 03 et 1a) par une autre qui n'est pas forcément de la même taille.
le tableau de départ:
► Afficher le texte
Le tableau à insérer:
► Afficher le texte
Le tableau que je souhaite obtenir à la fin:
► Afficher le texte
Voila le code que j'ai pondu pour le moment:

Code : Tout sélectionner

#include <Array.au3>

Local $tableau[15] = [ _
        "ff", _
        "03", _
        "00", _
        "00", _
        "00", _
        "00", _
        "00", _
        "00", _
        "00", _
        "00", _
        "00", _
        "00", _
        "00", _
        "1a", _
        "ff"]

Local $tableau2[3] = [ _
        "03", _
        "99", _
        "1a"]

_ArrayDisplay($tableau)

Local $index_depart = _ArraySearch($tableau, "03", 0, 0)
Local $index_arrivee = _ArraySearch($tableau, "1a", 0, 0)

MsgBox(0, "Index départ", $index_depart)
MsgBox(0, "Index arrivée", $index_arrivee)

For $i=$index_depart to $index_arrivee
    _ArrayDelete($tableau, $i)
    _ArrayDisplay($tableau)
Next

_ArrayDisplay($tableau)

_ArrayReverse($tableau2)

For $i=0 to Ubound($tableau2) - 1
    _ArrayInsert($tableau, $index_depart, $tableau2[$i])
    _ArrayDisplay($tableau)
Next

_ArrayDisplay($tableau)
 
Le problème c'est qu'il ne m'efface pas les bonnes lignes et je suis perdu je ne comprend pas pourquoi...

Merci de votre aide.
Modifié en dernier par clark17 le jeu. 27 mars 2014 17:03, modifié 1 fois.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#2

Message par mikell »

Explication dans le fichier d'aide :
"If the $iElement is greater than the array size then the last element is destroyed."

Démonstration :

Code : Tout sélectionner

For $i=$index_depart to $index_arrivee
    _ArrayDelete($tableau, $i)
    _ArrayDisplay($tableau, "index " & $i & " détruit !")
Next
Solution :

Code : Tout sélectionner

For $i=$index_depart to $index_arrivee
    _ArrayDelete($tableau, 1)
    _ArrayDisplay($tableau, "index 1 détruit !")
Next
Maintenant, pour moins stresser ton processeur tu peux aussi faire comme ça
► Afficher le texte
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
clark17
Niveau 4
Niveau 4
Messages : 70
Enregistré le : ven. 23 sept. 2011 02:12
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#3

Message par clark17 »

mikell a écrit :Solution :

Code : Tout sélectionner

For $i=$index_depart to $index_arrivee
    _ArrayDelete($tableau, 1)
    _ArrayDisplay($tableau, "index 1 détruit !")
Next
Autant pour moi j'avais pas pensé qu'avec une boucle mon nombre de ligne se réduisait! ;-)

Maintenant pour ta solution avec les regex c'est beaucoup plus élégant c'est clair. Je viens lire quelques tuto sur les regex c'est un peu plus clair.
Par contre je bloque toujours sur un point. Si je souhaite remplacer uniquement la deuxième occurrence, comment faire?
J'ai tenté ceci:
► Afficher le texte
Mais ça ne fonctionne pas...
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#4

Message par jchd »

Le facteur de répétition {2} ne fait pas ce que tu veux lui faire faire. Il équivaut à écrire ton pattern sous la forme "03.+?1a(03.+?1a)" d'un seul bloc, où seule les occurences paires de "03.+?1a" seraient capturées, donc remplacées. La chaîne sujet ne contient pas une telle séquence et elle est donc invariante par l'opération.

Ce qu'il te faut ici est différent :

Code : Tout sélectionner

$string3 = StringRegExpReplace($string1, '03.+?1a[b].+[/b](03.+?1a)', $string2, 1)
L'élément .+ en gras permet de passer outre les caractères qui se trouvent entre les séquences et, là, seule le groupe capturé sera remplacé.
Revois l'aide de la fonction et en particulier son dernier paramètre optionnel et la lumière éclairera ton visage d'un sourire de compréhension, au cas où il serait possible que le sujet contienne plus de deux fois la chaîne "03.+?1a" cherchée et que tu ne veuilles remplacer que la seconde occurence.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
clark17
Niveau 4
Niveau 4
Messages : 70
Enregistré le : ven. 23 sept. 2011 02:12
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#5

Message par clark17 »

J'avais regardé la doc et si je ne dis pas de bêtises me dernier paramètre est count. C'est le nombre d’occurrence à remplacer et non le n° de celle à remplacé ?
Dans mon exemple c'est bien seulement la deuxième occurrence que je cherche à remplacer. Par conséquent si je fais:

Code : Tout sélectionner

$string3 = StringRegExpReplace($string1, '(03.+?1a)', $string2, 2 )
 
cela me remplace les deux premières et pas seulement la deuxième...
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#6

Message par jchd »

Correct, mais ça n'a rien à voir avec la question que tu posais. Par principe, j'évite de répondre aux questions pas encore posées :mrgreen:
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#7

Message par mikell »

jchd si j'ai bien compris le but est à partir de cette chaine :
"ff,03,00,00,00,00,00,00,00,00,00,00,09,1a,ff,ff,03,00,00,00,00,00,00,00,00,00,00,00,1a,ff"
obtenir :
"ff,03,00,00,00,00,00,00,00,00,00,00,09,1a,ff,ff,03,99,1a,ff"
or ton expression

Code : Tout sélectionner

$string3 = StringRegExpReplace($string1, '03.+?1a.+(03.+?1a)', $string2, 1)
retourne "ff,03,99,1a,ff"
" 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
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#8

Message par jchd »

Oops, pas collé le bon clip :

Code : Tout sélectionner

$string3 = StringRegExpReplace($string1, '03.+?1a.+\K(03.+?1a)', $string2, 1)
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
clark17
Niveau 4
Niveau 4
Messages : 70
Enregistré le : ven. 23 sept. 2011 02:12
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#9

Message par clark17 »

En fait, ce que je cherche à faire c'est une fonction qui me remplace une chaine de caractère par une autre en spécifiant une occurrence précise.
Par exemple transformer:

Code : Tout sélectionner

03mot11a03mot21a03mot31a
En:

Code : Tout sélectionner

03mot11a03motmodifié03mot31a
En spécifiant l'occurrence n°2 dans ce cas.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#10

Message par mikell »

Attention quand tu parles d'occurences, en fait tu parles de plusieurs chaines identiques où tu veux remplacer la 2ème et pas les autres (par exemple)
"mot1" c'est pas la même chose que "mot2"

Code : Tout sélectionner

$string = "03MOT11a03MOT11a03MOT11a"
Msgbox(0,"",  _StringReplaceOcc($string, "MOT1", "tralala", 2) )

Func _StringReplaceOcc($string, $out, $in, $occur)
  Return StringRegExpReplace ($string, '(?:.*?\K' & $out & '){' & $occur & '}' , $in )  
EndFunc
Maintenant ça peut aussi être des chaines différentes mais correspondant au même motif (pattern...) de regex : "MOT1", "MOT2" etc

Code : Tout sélectionner

$string2 = "03MOT11a03MOT21a03MOT31a"
Msgbox(0,"",  _StringReplaceOcc2($string2, '(MOT\d)', "tralala", 2) )

Func _StringReplaceOcc2($string, $pattern, $in, $occur)
  $var = StringRegExpReplace ($string, '(?:.*?' &$pattern& '){' &$occur& '}.*' , '$1' )
  Return StringReplace ($string, $var, $in )  
EndFunc
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
clark17
Niveau 4
Niveau 4
Messages : 70
Enregistré le : ven. 23 sept. 2011 02:12
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#11

Message par clark17 »

mikell a écrit :Maintenant ça peut aussi être des chaines différentes mais correspondant au même motif (pattern...) de regex : "MOT1", "MOT2" etc

Code : Tout sélectionner

$string2 = "03MOT11a03MOT21a03MOT31a"
Msgbox(0,"",  _StringReplaceOcc2($string2, '(MOT\d)', "tralala", 2) )

Func _StringReplaceOcc2($string, $pattern, $in, $occur)
  $var = StringRegExpReplace ($string, '(?:.*?' &$pattern& '){' &$occur& '}.*' , '$1' )
  Return StringReplace ($string, $var, $in )  
EndFunc
C'est bien ça que je cherchais à faire! Je me suis effectivement mal exprimé sur les chaines différentes et non occurrences.
Maintenant j'essaye de comprendre la regex et là j'ai du mal.

La première ( ) c'est pour capturer le morceau.
Le ?: c'est pour lui dire de ne pas être gourmand et s'arrêter sur le premier 1a qu'il trouve?
Le .* c'est pour définir n'importe quels caractères.
Par contre le deuxième ? Je ne comprends pas son utilité?
Les {} pour définir sur quelle chaine il s’arrête.
Enfin le $1 qui correspond à ce qu'il trouve entre les parenthèses c'est ça?

Ensuite avec StringReplace tu changes ce que tu as trouvé avec la Regex.

Désolé pour ces questions, mais les regex me font mal à la tête!
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#12

Message par mikell »

?: c'est pour indiquer un groupe non-capturant (ne pas référencer le contenu)
.*? veut dire : n'importe quel caractère, 0 ou plusieurs fois, non-gourmand

Si on remplace les variables par des valeurs, le regex donne :

Code : Tout sélectionner

$var = StringRegExpReplace ($string2, '(?:.*?(MOT\d)){2}.*' , '$1' )
Ce qui est capturé et retourné par $1 est le groupe entre parenthèses
Donc là c'est le 2ème groupe (MOT\d) rencontré qui est référencé
Note que ça peut aussi s'écrire

Code : Tout sélectionner

$var = StringRegExpReplace ($string2, '(?:.*?(MOT\d))(?:.*?(MOT\d)).*' , '$2' )
Là on met $2 parce que dans l'expression figurent 2 groupes capturants

Code : Tout sélectionner

$string2 = "03MOT11a03MOT21a03MOT31a"

$var = StringRegExpReplace ($string2, '(?:.*?(MOT\d)){2}.*' , '$1' )
; $var = StringRegExpReplace ($string2, '(?:.*?(MOT\d))(?:.*?(MOT\d)).*' , '$2' )

$res = StringReplace ($string2, $var, "tralala")
Msgbox(0,"", "départ : " & $string2 &@crlf& "capture : " & $var &@crlf& "replace : " & $res)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
clark17
Niveau 4
Niveau 4
Messages : 70
Enregistré le : ven. 23 sept. 2011 02:12
Status : Hors ligne

Re: [..] Suppression puis ajout dans un tableau

#13

Message par clark17 »

Super merci je comprends mieux!
Répondre