StringReplace nur auf jede 2. Doppelziffe anwenden

  • Moin.

    Eingangsstring: "32 94 97 64 83 14 82 64 72" ; eigentliche Länge bis zu 200 zweistellige Zahlen.
    Ausgangsstring: "32 06 97 36 83 86 82 36 72" ; so SOLL ES aussehen

    Ich würde gerne jede zweite zweistellige Zahl "negativieren" (100 minus die Zahl). Ich benne es mal so. Hab keine Zeit mir ein anderes Wort auszudenken.
    Dachte: StringReplace 01 mit 99 ; 02 mit 98 ; 03 mit 97 ; ...
    Aber so werden alle zweistellige Zahlen genommen.

    :(

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Alina 7. Oktober 2022 um 22:30

    Hat den Titel des Themas von „StringReplace“ zu „StringReplace nur auf jede 2. Doppelziffe anwenden“ geändert.
  • Eingangsstring: "32 94 97 64 83 14 82 64 72" ; eigentliche Länge bis zu 200 zweistellige Zahlen.
    Ausgangsstring: "32 06 97 36 83 86 82 36 72" ; so SOLL ES aussehen

    Ich würde gerne jede zweite zweistellige Zahl "negativieren" (100 minus die Zahl).

    Hi Lina !

    Hier mal ein Lösungsvorschlag.

    Ich bin nicht sicher, ob Du die Leerzeichen zwischen den zweistelligen Zahlen benötigst, oder ob sie hier nur zur optischen Trennung dienen.

    Daher enthält das Skript beide Varianten (die nicht gewünschte einfach auskommentieren) .

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Hallo Alina ,

    hier mein Vorschlag mit einem Array, erstellt aus dem Code von Musashi , der eine sehr gute Vorlage lieferte:

    Dieser Code könnte jedoch langsamer, aber vielleicht leichter verständlich sein.

    Gruß, fee

  • Du kannst auch mit StringRegExp dich Schrittweise durch den String hangeln (z.B. über den Offset-Parameter).
    Dann hättest du ein bisschen mehr Flexibilität - z.B. eine Lösung für die Variante mit und ohne Leerzeichen:

  • So geht es auch:

  • Na gut, bei so vielen Lösungen fehlt ja eigentlich nur noch der obligatorische Einzeiler:

    AutoIt
    $sInput = "32 94 97 64 83 14 82 64 72"
    
    $sOutput = Execute("'" & StringRegExpReplace($sInput, '\d\d\s?\K(\d\d)', "' & StringFormat('%02d', 100 - \0) & '") & "'")
    
    ConsoleWrite($sOutput)
  • Bitnugger : Und wie erledigst du dann die Umwandlung des Arrays in einen String ohne zweite Schleife, vor allem wenn die Anzahl der Doppelziffern ungerade ist? Deinen Vorschlag hatte ich nämlich auch erst so geschrieben.

  • Und wie erledigst du dann die Umwandlung des Arrays in einen String ohne zweite Schleife, vor allem wenn die Anzahl der Doppelziffern ungerade ist?

    So würde ich es dann machen:

    2 Mal editiert, zuletzt von Bitnugger (8. Oktober 2022 um 18:15) aus folgendem Grund: Noch etwas verkürzt...

  • Bitnugger : Die verbleibende Doppelziffer nach der Schleife anzuhängen hatte ich mir ein kleines bisschen aufwändiger vorgestellt. Aber so ist es bestimmt schneller als dieses Mod-Gedöns und auch einfach zu verstehen. Sehr schöne Lösung!

  • 1.000 Dank an alle !

    Das spart mir nun den Weg das ganze über Excel.

    Die Eingangsdaten sind im Ordner m:\reno_u_gusv_dk\*.rns mit Leerzeichen getrennt gespeichert.
    Die Ausgangsdaten sind im Ordner m:\reno_u_gusv_dk\*.rnt mit Leerzeichen getrennt gespeichert.

    Edit 1:
    @Bitnugger den Aufruf von Dir , ohne Leerzeichen, den kann ich für das hier bestehende Problem nicht verwenden, aber ich kann es wo anders einsetzten.

    Edit 2:
    Und wenn ich es wieder anders rum benötige kann ich es genauso durchlaufen lassen. Weil die 100 ja ein fester Wert ist.  fee wandelt die 100 in 00 um und auch umgekehrt ! Das ist ja auch richtig. Bei den anderen Lösungen wird auch die 100 in 00 umgewandelt, aber umgekehrt kommt dann nicht wieder 100 raus.
    Auf die Idee hätte ich auch kommen können. Aber nie Bedarf nach gehabt, weil es ja über Excel eh vorlag.

    Nur jetzt werde ich mal sehen, das ich es irgendwie hin bekomme, das wenn eine neue *.rns im Ordner ist, das die *.rnt auftomatisch erstellt wird.
    Das habe ich schon mal gemacht und irgendwo habe ich also die Lösung auf Festplatte oder DVD.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

    4 Mal editiert, zuletzt von Alina (8. Oktober 2022 um 20:48)

  • fee wandelt die 100 in 00 um und auch umgekehrt ! Das ist ja auch richtig. Bei den anderen Lösungen wird auch die 100 in 00 umgewandelt, aber umgekehrt kommt dann nicht wieder 100 raus.

    Am Anfang schriebst du, dass die Eingabezeichenfolge nur zweistellige Zahlen enthält. Finde ich zwar schön, dass mein Vorschlag deine erweiterte Aufgabe richtig löst, was aber nicht von mir beabsichtigt und vor allem nicht ganz deine Aufgabenstellung war. ;)

    Naja, besser so als anders herum. :)

    Bei der Ordnerüberwachung kann ich dir allerdings nicht helfen, das habe ich noch nie gebraucht/gemacht.

    Edit: Den Mod()-Teil in meinem Vorschlag würde ich allerdings durch den Vorschlag von Bitnugger in Beitrag #10 ersetzen, also der For-Schleife ein Step 2 verpassen und danach die letzte Doppelziffer an ungerader Position (sofern vorhanden) verarbeiten. Spart Laufzeit, denn Modulo ist leistungshungrig.

    Einmal editiert, zuletzt von fee (8. Oktober 2022 um 22:45)

  • Am Anfang schriebst du, dass die Eingabezeichenfolge nur zweistellige Zahlen enthält. ...

    Genau...

    Ordnerüberwachung ist auch nicht schwierig...

    Einmal editiert, zuletzt von Bitnugger (9. Oktober 2022 um 15:39) aus folgendem Grund: #include <GUIConstantsEx.au3> hinzugefügt

  • Da habe ich mich falsch ausgedrückt?
    Ja, die Eingabezeichenfolge ist ja auch immer zweistellig ! Alles gut !

    Alles läuft nun bestens ! ! !

    Die Ordnerüberwachung sehe ich mir morgen an. Gleich geht es ins Bett !
    Das mit dem Mod Teil sehe ich mir dann auch an !

    DANKE EUCH ! ! !

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Alina : Gern geschehen! :)

    Bitnugger : Die Ordnerüberwachung wäre vermutlich toll, aber

    1. fehlt ein #include <GUIConstantsEx.au3> (nicht schlimm) und
    2. bekomme ich unter Win7 Pro x64 nur ein Event: 0x00040000 nach Hinzufügen einer RNS-Datei im Ordner.

    Leider verstehe ich (noch) nicht, warum.

    Edit:

    Bitnugger : So funktioniert es jetzt bei mir auf Win7 Pro x64, wenn ich eine RNS-Datei im zu überwachenden Ordner erstelle:

    Eine RNS-Datei in einen andernen Dateityp umbenennen würde erkannt werden, umgekehrt jedoch nicht. $SHCNE_ALLEVENTS kann somit vom Erkennungsumfang her auf BitOR($SHCNE_ASSOCCHANGED, $SHCNE_CREATE) reduziert werden. Die rekursive Erkennung habe ich auch entfernt, um Leistung einzusparen. $SHCNE_UPDATEITEM tritt laut Beschreibung nur bei Veränderung des Inhaltes eines Elementes auf, hier also nicht nötig. $SHCNE_CREATE habe ich aus der Funktion _WM_SHELLCHANGENOTIFY() entfernt.

    Die Beschreibung zu SHChangeNotifyRegister empfiehlt statt BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL) den Wert $SHCNRF_NEWDELIVERY in der Funktion _WinAPI_ShellChangeNotifyRegister():

    Messages received use shared memory. Call SHChangeNotification_Lock to access the actual data. Call SHChangeNotification_Unlock to release the memory when done.

    Note: We recommend this flag because it provides a more robust delivery method. All clients should specify this flag.

    Den ersten Zitatsatz weiß ich leider nicht vollständig umzusetzen. Macht aber nix, für mich funktioniert es auch so.

    7 Mal editiert, zuletzt von fee (9. Oktober 2022 um 08:13)

  • fehlt ein #include <GUIConstantsEx.au3>

    Oh ja, habe ich nun hinzugefügt...

    Eine RNS-Datei in einen andernen Dateityp umbenennen würde erkannt werden, umgekehrt jedoch nicht.

    Ja, will man das, muss die Abfrage entsprechen angepasst werden... den alten Namen bekommst du mit "Item1", den neuen mit "Item2".

    $SHCNE_UPDATEITEM tritt laut Beschreibung nur bei Veränderung des Inhaltes eines Elementes auf, hier also nicht nötig.

    Wir benötigen ja nicht nur den Namen des Pfades, sondern vor allem auch den Inhalt der Datei... den es aber evtl. noch nicht gibt, nachdem die Datei erstellt wurde ($SHCNE_CREATE) - z.B. mit FileOpen("filename.rns", $FO_OVERWRITE) - hier greift dann $SHCNE_UPDATEITEM, nachdem die Daten geschrieben wurden!

    Da die Aufgabenstellung nur das Erkennen von neuen *.rns vorgibt, brauchen wir $SHCNE_CREATE und $SHCNE_UPDATEITEM, jedoch kein $SHCNE_ASSOCCHANGED. Das kann man natürlich auch noch abfragen, genauso wie $SHCNE_RENAMEITEM, wenn die Datei umbenannt wurde und nun vielleicht keine *.rns mehr ist. Das war aber nicht gefragt.

    Den ersten Zitatsatz weiß ich leider nicht vollständig umzusetzen.

    So habe ich das verstanden:

    Durch $SHCNRF_NEWDELIVERY wird für empfangene Nachrichten gemeinsam genutzter Speicher verwendet. SHChangeNotification_Lock rufst du auf, um auf die eigentlichen Daten zuzugreifen. SHChangeNotification_Unlock rufst du auf, um den Speicher wieder freizugeben, wenn du fertig sind.


    Schau mal hier, wie KaFu das gelöst hat.

    Ansonsten... sehr schön umgesetzt. :rock:

    Hier noch meine Version - die *.rnt wird hiermit auch erstellt:

  • @Bitnugger
    Also das Umwandeln funktioniert TOP.
    Das Anzeigen das eine neue Datei im Ordner ist erfolgt bei mir nicht. Die GUI baut auf, aber sie füllt sich nicht, sobald eine weitere Datei in den Ordner kommt.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Bitnugger :

    den alten Namen bekommst du mit "Item1", den neuen mit "Item2".

    Okay, das wusste ich nicht.

    Wir benötigen ja nicht nur den Namen des Pfades, sondern vor allem auch den Inhalt der Datei... den es aber evtl. noch nicht gibt, nachdem die Datei erstellt wurde ($SHCNE_CREATE) - z.B. mit FileOpen("filename.rns", $FO_OVERWRITE) - hier greift dann $SHCNE_UPDATEITEM, nachdem die Daten geschrieben wurden!

    Ups, das hatte ich nicht bedacht.

    jedoch kein $SHCNE_ASSOCCHANGED.

    Das habe ich mit reingenommen, weil in der Beschreibung steht:

    This event should also be sent for registered protocols.

    Muss ich dann wohl missverstanden haben. Ein Dateityp ist ja kein Protokoll, oder?

    Schau mal hier, wie KaFu das gelöst hat.

    Uff, den *_Lock und *_Unlock-Teil hätte ich vielleicht noch hinbekommen können, aber allerspätestens bei _WinAPI_ShellChangeNotifyRegisterEx wäre für mich Schluss gewesen.

    Ansonsten... sehr schön umgesetzt. :rock:

    Danke dir. :) Deine neue Version ebenso!

    Alina :

    Das Anzeigen das eine neue Datei im Ordner ist erfolgt bei mir nicht. Die GUI baut auf, aber sie füllt sich nicht, sobald eine weitere Datei in den Ordner kommt.

    Klar, weil Bitnugger kein Edit-Element wie ich in die GUI eingebaut hat und Meldungen zum Debuggen in der SciTE-Konsole ausgeben lässt, sofern das Skript von SciTE aus gestartet wurde.

  • fee
    Ich blicke da noch nicht so durch was Bitnugger gescriptet hat. Aber ich versuche es zu verstehen und dann sehe ich mal weiter.

    Aber Dank !

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl