Einzelne Daten (Mengenproblem) in einem String durch array austauschen?

  • hallo zusammen,

    ich bin anfänger in AutoIT, aber ich möchte einige zusammenhänge verstehen. ich mache das alles mit einem hintergrund, dass ich etwas erschaffen moechte was mir seit jahren im kopf haengt und ich immer wieder massive rueckschlaege habe und dann ploetzlich die lust verliere, bis ich mich dann mal wieder aufraffen kann weiterzumachen. Im moment bin ich aber wieder in der lernkurve, also kopf hoch und weitermachen.

    hier ein script womit ich worte in einem string mittels array austauschen kann. funktioniert super:

    Code
    $satz = "hallo dies ist ein toller & guter text!"
    Global $ersatz[100][2] = [[8], ["hallo","warum"],["dies","kann"],["ist","ich"],["ein","AutoIT"], _
    ["toller","nicht"],["&","ganz"],["guter","vollstaendig"],["text!","verstehen?"]] ;8 Veraenderungen
    For $i = 1 To $ersatz[0][0]
       $satz = StringRegExpReplace($satz, "\Q" & $ersatz[$i][0] & "\E", $ersatz[$i][1])
        ConsoleWrite($satz & @CRLF)
        sleep(1000)
    Next
    MsgBox(0,"","Muss sein:" & @CRLF & "warum kann ich AutoIT nicht ganz vollstaendig verstehen?" & @CRLF & @CRLF & "Ist aber:" & @CRLF & $satz)

    ConsoleWrite() laeuft 8 mal durch und veraendert nach und nach den ganzen satz:

    Code
    warum dies ist ein toller & guter text!
    warum kann ist ein toller & guter text!
    warum kann ich ein toller & guter text!
    warum kann ich AutoIT toller & guter text!
    warum kann ich AutoIT nicht & guter text!
    warum kann ich AutoIT nicht ganz guter text!
    warum kann ich AutoIT nicht ganz vollstaendig text!
    warum kann ich AutoIT nicht ganz vollstaendig verstehen?

    Nun dachte ich mir, das klappt ja super. mal sehen wie 'verrückt' ich damit werden kann. also tauschen wir jetzt einfach mal einzelne buchstaben aus:

    Code
    $satz2 = "hallo dies ist ein toller & guter text!"
    Global $ersatz2[100][2] = [[29], ["a","m"],["b","n"],["c","o"],["d","p"],["e","q"],["f","r"],["g","s"],["h","t"], _
    ["i","u"],["j","v"],["k","w"],["l","x"],["m","y"],["n","z"],["o","a"],["p","b"],["q","c"],["r","d"],["s","e"], _
    ["t","f"],["u","g"],["v","h"],["w","i"],["x","j"],["y","k"],["z","l"],["!","1"],["&","2"],[" ","_"]] ;29 Veraenderungen
    For $i = 1 To $ersatz2[0][0]
       $satz2 = StringRegExpReplace($satz2, "\Q" & $ersatz2[$i][0] & "\E", $ersatz2[$i][1])
        ConsoleWrite($satz2 & @CRLF)
        sleep(1000)
    Next
    MsgBox(0,"","Muss sein:" & @CRLF & "tmxxa_piqe_uef_quz_faxxqd_2_sgfqd_fqjf1" & @CRLF & @CRLF & "Ist aber:" & @CRLF & $satz2)

    tja ... da machen sich dann fehler bemerkbar: da alles 29 mal durchlaeuft, werden auch buchstaben ersetzt, die bereits ersetzt waren und dann verfaelscht sich das ergebnis:

    ConsoleWrite() laeuft 29 mal durch und veraendert nach und nach jeden buchstaben:

    also zusammenfassend: das script geht, aber es geht auch gleichzeitig nicht. sobald man auf den kleinsten nenner (ein einzelner buchstabe) reduziert werden einzelne buchstaben den umwandlungsprozess mehrmals durchlaufen (a=m ... m=y ... y=k). das ist nicht wirklich das erhoffte ergebnis.

    ich bin also irgendwo falsch abgebogen. die frage ist nur 'wo'? und 'warum?'

    irgendwelche kommentare oder ideen? - ist es überhaupt möglich einen string so sehr zu manipulieren?

    ich gehe stark davon aus, dass ich das über multiple instanzen machen muesste? also nach jeden durchlauf ein neues array schaffen und dan daraus ein gesamtergebnis erstellen?

    gruss

    ConsoleWrite("=====================>>> "&"About Me:"&" <<<=====================" & @CRLF)
    ConsoleWrite("Someday I will know how to do it but that day is not today!" & @CRLF)
    ConsoleWrite("===================>>> "&"bankesbusters"&" <<<===================" & @CRLF)

  • Falsch abgebogen bist du nicht.
    Das Skript macht das was es soll und das ist genauso wie von dir bereits festgestellt: Die bereits prozessierten Zeichen werden von den danach kommenden Anweisungen wieder mit erfasst.

    Um damit umzugehen gibt es ein paar Ansätze.
    Einer wäre es, bereits prozessierte Daten zu escapen indem man z.B. einen Präfix voranstellt oder soetwas in der Art.
    Dann sagt man dem Ersetzungsgbefehl, dass die Zeichen, welche den Präfix haben nicht prozessiert werden sollen.
    Ganz am Ende dann wird das Escapezeichen dann entfernt und das Ergebnis sollte dein gewünschtes sein.

    Da wir uns hier im Forum "Programmieranfragen" befinden wäre das ganze auch gleich folgendermaßen umgesetzt (dann sieht man auch gleich, dass in deinem Solltext noch ein kleiner Fehler steckt):

  • AutoIt
    [ ... ]
    Global $aErsatz[][] = [["a","m"],[ ...],[" ","_"]] ; die Veraenderungen
    [ ... ]

    hallo,

    ich spreche jetzt 'AspirinJunkie' gezielt an, weil ich im obigen teil eine verständnisfrage habe:

    nach vielen experimenten verstehe ich nicht ganz wieso bei mir quasi

    Global $aErsatz[100][2] = [[29], ["a","m"],[ ...],[" ","_"]] ; die Veraenderungen

    zahlen da stehen muessen und bei dem beispiel auf jegliche angaben verzichtet wird. ... seltsam. ich war der meinung, man kann immer schick etwas leicht anpassen, aber das ist ein grosser trugschluss.

    ---

    der rest ist glaube ich gut nachvollziehbar und sogar eine grandiose idee. das gefaellt mir sehr gut. damit kann ich arbeiten. das ist wirklich toll.

    ich glaube es folgen nur nur noch zwei grundlegende themen und dann kann ich mit dem zusammenbau meines projekts beginnen. aber bevor ich frage will ich immer zuerst wenigstens selber probieren und ggf. scheitern und erst dann stelle ich fragen. weil: wenn ich es nicht wenigstens selber versuche bringt es mir nichts auf lange sicht.

    trotzdem vielen dank für den genialen tip. da freue ich mich sehr.

    gruss

    ConsoleWrite("=====================>>> "&"About Me:"&" <<<=====================" & @CRLF)
    ConsoleWrite("Someday I will know how to do it but that day is not today!" & @CRLF)
    ConsoleWrite("===================>>> "&"bankesbusters"&" <<<===================" & @CRLF)

  • Bei dir steht in deinem Array im ersten Element (Index [0][0]) die Anzahl der Zeilen des Arrays.
    Das heißt: Irgendjemand muss sich darum kümmern, dass dort die korrekte Anzahl steht - in deinem Fall du selbst.
    Die Anzahl der Zeilen des Arrays ist aber eine immante Eigenschaft des Arrays, welche man ganz einfach mit der Funktion Ubound() abfragen kann.
    Sprich: Das kann man sich alles sparen.

    Da die Variante mit Ubound() also die sicherere ist, habe ich dies entsprechend umgestellt.
    Das hat auch den Nebeneffekt, dass die Daten in deinem Array nun beim Index 0 beginnen anstatt wie vorher bei 1.
    Und da Ubound die Anzahl der Zeilen zurückgibt und die Indizes aber bei 0 beginnen, ist der letzte Index im Array = Anzahl Zeilen - 1

  • ich arbeite hier und da mit Ubound und das mit dem -1 kenne ich, aber es schein vielseitiger zu sein als zunaechst gedacht.

    mega. danke fuer die erklaerung, ich denke da nehme ich dann auch nocht ein wenig 'wissen' mit worauf ich mehr achten muss.

    vielen dank.

    ConsoleWrite("=====================>>> "&"About Me:"&" <<<=====================" & @CRLF)
    ConsoleWrite("Someday I will know how to do it but that day is not today!" & @CRLF)
    ConsoleWrite("===================>>> "&"bankesbusters"&" <<<===================" & @CRLF)