1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. BugFix

Beiträge von BugFix

  • Nutzergesteuerte Datum/Zeit-Ausgabe

    • BugFix
    • 11. August 2014 um 18:27

    Folgendes ist bei einem Projekt von mit angefallen:

    Der Nutzer soll vollkommen frei und für ihn verständlich Tagesdatum/Zeit oder beliebige Elemente daraus formatieren können.
    Folgende Makros stehen zur Verfügung:
    YYYY / YY - Jahr 4/2 -stellig
    MM / M - Monat 2/1 -stellig
    DD / D - Tag 2/1 -stellig
    hh / h - Stunde 2/1 -stellig
    mm / m - Minute 2/1 -stellig
    ss / s - Sekunde 2/1 -stellig
    ww / w - Wochentag lang/kurz (Montag/Mo)
    Bsp. "YYYY-MM-DD", "YYYYMMDD", "D.M.YY", "ww, DD.MM.YYYY", "DD.MM.YYYY hh:mm:ss" (Standard)
    Einstellig bedeutet, wenn einstelliger Wert, wird er auch einstellig ausgegeben. Zweistellig fügt dann eine Vornull an.
    Optional gibt es die Möglichkeit einen String vorne und/oder hinten anzufügen.
    Die vom User gewünschte Formatierung kann z.B. aus einer INI eingelesen und von diesem intuitiv angepasst werden.

    Spoiler anzeigen
    [autoit]

    ;===============================================================================
    ; Function Name....: _DateTimeUser
    ; Description......: Nutzergesteuerte Datum- und/oder Zeitausgabe
    ; Parameter(s).....: $_time_format Nutzerdefiniertes Ausgabeformat
    ; .................: Makros YYYY / YY - Jahr 4/2 -stellig
    ; .................: MM / M - Monat 2/1 -stellig
    ; .................: DD / D - Tag 2/1 -stellig
    ; .................: hh / h - Stunde 2/1 -stellig
    ; .................: mm / m - Minute 2/1 -stellig
    ; .................: ss / s - Sekunde 2/1 -stellig
    ; .................: ww / w - Wochentag lang/kurz (Montag/Mo)
    ; .................: Bsp. "YYYY-MM-DD", "YYYYMMDD", "D.M.YY", "DD.MM.YYYY hh:mm:ss" (Standard)
    ; .................: "ww, DD.MM.YYYY"
    ; .................: Auch einzelne Werte und beliebige Kombinationen können abgefragt werden. "DD-hh-mm"
    ; ....[optional]...: $_pre vorangestellter String
    ; ....[optional]...: $_post nachgestellter String
    ; Return Value(s)..: Der formatierte Datum/Zeitstring für das heutige Datum
    ; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
    ;===============================================================================
    Func _DateTimeUser($_time_format='', $_pre='', $_post='')
    $_time_format = ($_time_format = '') ? 'DD.MM.YYYY hh:mm:ss' : $_time_format
    Local $aTime[10][2] = [['MM', @MON], ['DD', @MDAY], ['hh', @HOUR], ['mm', @MIN], ['ss', @SEC], _
    ['M', @MON], ['D', @MDAY], ['h', @HOUR], ['m', @MIN], ['s', @SEC]]
    StringReplace($_time_format, 'Y', 'Y')
    Local $sYear = StringLeft('YYYY', @extended), $output = $_time_format
    Local $srepl = (StringLen($sYear) < 4) ? StringRight(@YEAR, 2) : @YEAR
    If $sYear <> '' Then _
    $output = StringReplace($_time_format, $sYear, $srepl)
    Local $sformat
    For $i = 0 To 9
    $sformat = '%0' & StringLen($aTime[$i][0]) & 'd'
    $output = StringReplace($output, $aTime[$i][0], StringFormat($sformat, $aTime[$i][1]), 1, 1)
    Next
    If StringInStr($output, 'w') Then
    Local $YY = StringRight(@YEAR, 2), $aMonval[13] = ['',0,3,3,6,1,4,6,2,5,0,3,5], $iDiff
    Local $Y_val = Mod(($YY + Int($YY/4)), 7), $M_val = $aMonval[@MON], $D_val = @MDAY
    Local $aY_val[7][2] = [[2300,0],[2200,2],[2100,4],[2000,6],[1900,0],[1800,2],[1700,4]]
    For $i = 0 To 6
    If @YEAR >= $aY_val[$i][0] Then
    $iDiff = $aY_val[$i][1]
    ExitLoop
    EndIf
    Next
    If ((Mod(@YEAR,400)=0)?1:(Mod(@YEAR,100)=0)?0:(Mod(@YEAR,4)=0)?1:0) Then $iDiff -= 1
    Local $aWDay[7][2] = [['Sonntag','So'],['Montag','Mo'],['Dienstag','Di'],['Mittwoch','Mi'], _
    ['Donnerstag','Do'],['Freitag','Fr'],['Samstag','Sa']]
    Local $w = Mod($Y_val + $M_val + $D_val + $iDiff, 7)
    $output = StringReplace($output, 'ww', $aWDay[$w][0], 1, 1)
    $output = StringReplace($output, 'w', $aWDay[$w][1], 1, 1)
    EndIf
    Return $_pre & $output & $_post
    EndFunc ;==>_DateTimeUser

    [/autoit]

    Die Wochentags- und Schaltjahrermittlung habe ich bewußt ohne externe Funktionen berechnet, damit diese Funktion auch ohne Includes auskommt.

  • Halbdynamisches Array - verbessert die Performance von Größenänderungen erheblich

    • BugFix
    • 11. August 2014 um 13:19

    Ja, wenn man es wirklich intuitiv führen wollte, müsste man alle Aufrufe für Pop/Push/Delete oder was noch hinzukommt, über einen Wrapper jagen, der dann die richtige Funktion auswählt und entsprechend den Zähler manipuliert. Wobei das noch einfach ist. Eine automatische Erkennung, welches Array denn gerade übergeben wird, kann man ja auch nicht ohne Verrenkungen realisieren. Das erfordert dann irgendeine Form der Registrierung/ID-Vergabe. Stimmt schon - optimal geht anders.. ;)

  • Halbdynamisches Array - verbessert die Performance von Größenänderungen erheblich

    • BugFix
    • 11. August 2014 um 13:05
    Zitat von AspirinJunkie

    _DynArrayPush? Diese wird ja erst aufgerufen wenn das Array schon erstellt habe.
    Und wenn ich das Array dann nicht mehr benötige und lösche? Vielleicht sogar mit einer Funktion _ArrayDelete(). Wie lösche ich dann dessen Eintrag in der statischen Variable?

    Die Verwaltung wird mit in die Funktion eingebunden, das erfordert dann, dass das Löschen auch damit vorgenommen wird:

    Spoiler anzeigen
    [autoit]

    Global $ar_1[1]
    Global $ar_2[1]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To 20
    ConsoleWrite(_DynArrayPush($ar_1, $i, 1) & @LF)
    If Mod($i, 2) = 0 Then ConsoleWrite(_DynArrayPush($ar_2, $i, 2) & @LF) ; nur jedes 2.te mal ausführen
    ConsoleWrite('Loop_' & $i & ': UBound $ar_1 = ' & UBound($ar_1) & ', UBound $ar_2 = ' & UBound($ar_2) & @LF)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _DynArrayPush($ar_2, '', -2)
    ConsoleWrite('IsArray( $ar_2 :( ' & IsArray($ar_2) & @LF)

    [/autoit] [autoit][/autoit] [autoit]

    Func _DynArrayPush(ByRef $a_Array, $value, $index)
    If Not IsArray($a_Array) Then Return SetError(1, 0, False)

    [/autoit] [autoit][/autoit] [autoit]

    ; ---- Zählerverwaltung
    Local Static $aCounter[100] ; belegen ab Index 1, [0] bleibt ungenutzt
    If $index < 0 Then
    $aCounter[Abs($index)] = 0 ; negativer Index löscht Einträge
    $a_Array = '' ; evtl. das Array auch gleich leeren ?
    Return
    EndIf
    ; ----

    [/autoit] [autoit][/autoit] [autoit]

    Local $w = UBound($a_Array)
    ;~ $a_Array[0] += 1
    ;~ Local $N = $a_Array[0]
    $aCounter[$index] += 1
    Local $N = $aCounter[$index] -1

    [/autoit] [autoit][/autoit] [autoit]

    If $N > $w Or (Not IsInt($N)) Then Return SetError(2, 0, False)

    [/autoit] [autoit][/autoit] [autoit]

    If $N = $w Then ReDim $a_Array[2 * $w] ; verdopple falls Array-Grenze erreicht wurde
    $a_Array[$N] = $value
    Return True
    EndFunc ;==>_DynArrayPush

    [/autoit]
  • Halbdynamisches Array - verbessert die Performance von Größenänderungen erheblich

    • BugFix
    • 11. August 2014 um 11:41

    Ich handhabe das ähnlich, allerdings nicht mit Verdopplung der Arraygröße, sondern ich stimme das für die Anwendungen einzeln ab.
    Dabei gehe ich von einer vorerst zu erwartenden realistischen Arrayobergrenze $max aus. 20% davon werden bereitgestellt. Jeweils bei Erreichen dieser Grenze wird das Array um den gleichen Wert erhöht. Bei Erreichen von $max wechsele ich von der statischen Vergrößerung (20% von $max) auf eine dynamische Vergrößerung (20% von UBound), sodass mit wachsender Arraygröße dann auch größere Häppchen angefügt werden.
    Wobei man vllt. auch sagen sollte, dass es hier um Arrays mit wirklichem Inhalt geht, also ich betrachte als Untergrenze 800-1000 Elemente. Was kleiner zu erwarten ist, wird in einem Aufwasch definiert. Ausnahme wäre, wenn ich im Array speicherlastige Inhalte ablege (andere Arrays, Objekte) und allgemein in einer speicherarmen Umgebung bin.
    Wer statistisch veranlagt ist, kann ja mal austesten, wie die unterschiedlichen Herangehensweisen mit der Arraygröße korrelieren.

    Zitat

    Zwang zur Notation der Elementanzahl im ersten Element

    Das läßt sich umgehen, mit einer Statischen Variable in deiner Arrayfunktion. Ich würde ein Static Array einbinden und als zusätzlichen Parameter einen Index, damit die Funktion für mehrere Array gleichzeitig genutzt werden kann. Im Static Array am übergebenen Index den Zähler für das jeweilige zu ändernde Array eintragen.

  • Performance-Analyse der neuen Datenstruktur "Map"

    • BugFix
    • 10. August 2014 um 18:05
    Zitat von Mars

    2. Im Aufruf muss eine $self (oä) Variable bestehen die ByRef auf die Map wirken kann.


    self könntest du als Static zwar erzeugen aber ByRef wird wohl nix werden. Das Problem besteht ja auch bei AutoItObject.

  • StringFormat - String links kürzen

    • BugFix
    • 10. August 2014 um 15:29
    Zitat von AspirinJunkie

    Warum nicht StringRight?


    Ich erstelle in einer Funktion den Formatstring in Abhängigkeit von einer Nutzereingabe. Der User legt in der INI eine Maske fest (z.B. Monat "M"=einstellig, wenn möglich oder "MM"=immer zweistellig). Den Formatstring erstelle ich dann einheitlich mit "%0" & StringLen($Maske) & "d" und kann das auf Jahr, Monat oder Tag gleichermassen mit der jeweiligen Maske anwenden ohne auf die einzelenen Segmente separat eingehen zu müssen.
    Klar kann ich eine zusätzliche Codezeile für den Jahresstring einbauen, fände es anders aber eleganter. Nunja - was nicht geht, geht nicht.

  • StringFormat - String links kürzen

    • BugFix
    • 10. August 2014 um 14:46

    Hi,
    StringFormat ist ja ganz praktisch um einheitlich formatierte Ausgaben zu erstellen. Ausgabelänge und Ausrichtung kann man vorgeben, Strings können auf eine bestimmte Anzahl Zeichen begrenzt werden.
    Und hier ist mein Problem. Diese Begrenzung greift immer von links nach rechts. Nehmen wir mal an, ich möchte eine Jahreszahl 2-stellig ausgeben. Dann brauche ich ein Ausgabe der letzten 2 Stellen. Die ersten 2 Stellen müssten somit gekürzt werden. Mir ist jedoch nur Folgendes möglich:

    Spoiler anzeigen
    [autoit]

    ; Formatierung: '%[-][anzuzeigende Stringlänge].[Genauigkeit]'
    ; [-]= String wird links ausgerichtet, sonst rechts

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(StringFormat('%.1s', @YEAR) & @LF) ;==> 2
    ConsoleWrite(StringFormat('%.2s', @YEAR) & @LF) ;==> 20
    ConsoleWrite(StringFormat('%.3s', @YEAR) & @LF) ;==> 201
    ConsoleWrite(StringFormat('%.4s', @YEAR) & @LF) ;==> 2014

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(StringFormat('%4.1s', @YEAR) & @LF) ;==> 2
    ConsoleWrite(StringFormat('%4.2s', @YEAR) & @LF) ;==> 20
    ConsoleWrite(StringFormat('%4.3s', @YEAR) & @LF) ;==> 201
    ConsoleWrite(StringFormat('%4.4s', @YEAR) & @LF) ;==> 2014

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(StringFormat('%-.1s', @YEAR) & @LF) ;==> 2
    ConsoleWrite(StringFormat('%-.2s', @YEAR) & @LF) ;==> 20
    ConsoleWrite(StringFormat('%-.3s', @YEAR) & @LF) ;==> 201
    ConsoleWrite(StringFormat('%-.4s', @YEAR) & @LF) ;==> 2014

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(StringFormat('%-4.1s', @YEAR) & @LF) ;==> 2
    ConsoleWrite(StringFormat('%-4.2s', @YEAR) & @LF) ;==> 20
    ConsoleWrite(StringFormat('%-4.3s', @YEAR) & @LF) ;==> 201
    ConsoleWrite(StringFormat('%-4.4s', @YEAR) & @LF) ;==> 2014

    [/autoit]

    Ist euch ein Weg bekannt, ob und wie ich mit StringFormat n Zeichen von rechts ausgeben kann?

  • Performance-Analyse der neuen Datenstruktur "Map"

    • BugFix
    • 10. August 2014 um 10:11

    minx
    :D
    Ja, eine "Objektisierung" läßt sich damit durchaus erreichen. Aber mal ehrlich: Meinst du irgendjemand kann diesen Code dann noch entziffern? ;)
    Es ist super, wenn man durch Verbiegen der Syntax tolle Side-Effekte erreicht. Doch dann bitte jede Codezeile mit 3 Kommentarzeilen versehen, damit du später auch selbst durch dieses 'Gewirr' durchsteigst. :P

  • Performance-Analyse der neuen Datenstruktur "Map"

    • BugFix
    • 9. August 2014 um 19:34

    Mal vorweg: Ich bin Beta-Verweigerer und habe somit noch keinen Blick auf diese Struktur geworfen.
    Ich denke, hier treffen verschiedene Vorstellungen aufeinander. Dem Einen ist es recht, wenn der Funktionsumfang der Sprache so groß wie möglich ist, dem Anderen reicht eine schmale Basis, die man gern durch UDF aufpeppen kann. Und hier gibt es vermutlich für beide Seiten ausreichend Für und Wider. Einen gemeinsamen Nenner können wir eh nicht stellen - den legt Jos fest. :D

  • AutoIt mit Sublime Text 2/3 -- Sprachdef. f. Stable v3.3.12.0, Wrapper, Au3Check, Run m. Parameter

    • BugFix
    • 8. August 2014 um 21:30

    Ich habe mir jetzt folgendes Konzept überlegt:
    - Abfrage ob in den Settings ein Backup-Pfad angegeben ist
    -- JA: dieser wird verwendet
    -- NEIN:
    --- Abfrage ob die aktuelle Datei in einem Projekt ist (und Ermittlung des Ordners, in dem sich die PROJEKTNAME.sublime-project befindet)
    ---- NEIN: Aktueller Dateipfad wird wird im Eingabepanel zur Übernahme/Änderung angeboten
    ---- JA: Prüfung ob bereits Backupordner im Projektpfad existiert
    ----- JA: Backup in diesen Ordner
    ----- NEIN: Projektordner wird im Eingabepanel zur Übernahme/Änderung angeboten

    Der Gedanke mit dem erstmaligen Speichern war Blödsinn. Das PlugIn ist (wie die meisten anderen auch) Suffix-abhängig und somit muss die Datei sowieso schon exitieren.

  • AutoIt mit Sublime Text 2/3 -- Sprachdef. f. Stable v3.3.12.0, Wrapper, Au3Check, Run m. Parameter

    • BugFix
    • 8. August 2014 um 18:00
    Zitat von rynow

    Wie könnte ich deine Backup Lösung so umschreiben, dass die Backups im Projekt Order landen?


    Das ist nach näherer Betrachtung Blödsinn. Ein Projekt ist ein virtueller Raum. Du kannst beliebig viele Pfade und Dateien in das Projekt verlinken. Somit gibt es gar nicht den Projektordner.
    Ich überdenke folgende Lösung:
    - Ist ein Pfad für Backups in den Settings enthalten, wird dort abgespeichert.
    - Ohne Angabe eines Pfades wird im aktuellen Pfad der Datei ein Ordner "BUp_Dateiname" angelegt und dort die jeweilige Version gespeichert. Das bedeutet aber dann, dass beim erstmaligen Speichern der Datei (also wenn sie gerade erstellt wird), noch kein Backup angelegt werden kann (mangels Pfad). Nicht so goldig.
    Werde ich noch etwas drüber grübeln.

  • _SQLite_Qry2Excel SQLiteabfrage in Exceltabelle schreiben

    • BugFix
    • 7. August 2014 um 16:04
    Zitat

    Kein Plan ob es schon was besser/ integriertes in AutoIt gibt


    Die Verwendung von Range und Übergabe der Range an ein Array liest die Excel-Tabelle in Null-Komma-Nichts aus.
    In der neuen Excel-UDF von water ist eine entsprechende Funktion (ich glaub _Excel_ReadRange), die diese Funktionalität nutzt.

  • AutoIt mit Sublime Text 2/3 -- Sprachdef. f. Stable v3.3.12.0, Wrapper, Au3Check, Run m. Parameter

    • BugFix
    • 7. August 2014 um 15:02

    Bin zur Zeit auf Dienstreise, wird also noch etwas warten müssen ;)

  • Dictionary dynamsch erstellen

    • BugFix
    • 7. August 2014 um 14:00
    Zitat von Racer

    Jetzt würde ich aber für dynamische Kategorien (werden durch den Benutzer erzeugt = weiß nicht wie viele es geben wird) ein eigenes Dictionary benötigen. Am Ende beinhaltet des Dictionary (=Kategorie) viele Daten!

    Also soll es
    - nur EIN Dictionary sein und die Schlüssel-Wert-Paare erzeugen die Nutzer?

    Zitat von Racer

    Ein Array fällt leider aus - das wäre für meine Aufgabenstellung mehr sehr schwer möglich!


    - Wieso denn das? Mit einem Array kannst du auch erledigen, was mit einem Dictionary geht. ;)

  • Suche Elegante Lösung zur Vermeidung Globaler Variablen.

    • BugFix
    • 7. August 2014 um 12:26

    Wie wäre es so:

    [autoit]


    ; Inhalte aus INI - das kannst du natürlich als Array einlesen und dann in einer Schleife abarbeiten

    [/autoit][autoit][/autoit][autoit]

    _MyVars('saUDF_Information_Anrede', '[CLASS:Edit;INSTANCE:8]', 'set')
    _MyVars('saUDF_Information_Name', '[CLASS:Edit;INSTANCE:9]', 'set')
    _MyVars('saUDF_Information_Vorname', '[CLASS:Edit;INSTANCE:10]', 'set')

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite(_MyVars('saUDF_Information_Name') & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    Func _MyVars($_strVarName, $_value='', $_action='get')
    Local Static $oDict = ObjCreate('Scripting.Dictionary')
    Switch $_action
    Case 'get'
    If $oDict.Exists($_strVarName) Then
    Return $oDict.Item($_strVarName)
    Else
    Return SetError(1,0,'')
    EndIf
    Case 'set'
    If Not $oDict.Exists($_strVarName) Then
    $oDict.Add($_strVarName, $_value)
    Else
    $oDict.Item($_strVarName) = $_value
    EndIf
    EndSwitch
    EndFunc

    [/autoit]

    Edit: Ich hatte vergessen, dass Werte auch zur Laufzeit geändert werden können - jetzt korrigiert.

  • RegExp - Backreferenz negieren?

    • BugFix
    • 7. August 2014 um 12:15

    Folgendes Szenario:
    Ein String enthält einfach und 3-fach quotierte Substrings.
    Hallo und 'Str_a' und '''Str_a1''' und "Str_b" und """Str_b1"""

    Ich möchte jetzt alle Quotierungen auslesen.
    Nur ' und '''
    ginge so:

    [autoit]


    $match = StringRegExp($s, "'([^']+)'", 3)
    _ArrayDisplay($match)

    [/autoit]

    Und Quotierung mit " oder """ finde ich so

    [autoit]


    $match = StringRegExp($s, '"([^"]+)"', 3)

    [/autoit]


    Nun wäre es schön, das in einem Aufruf zu erledigen.
    Mit Backreferenz auf das gefundene Quotierungszeichen geht das auch fein.

    [autoit]


    $match = StringRegExp($s, '("' & "|'" & ')([\w]+)\1', 3)
    _ArrayDisplay($match)

    [/autoit]


    Nun ist es aber nicht ausgeschlossen, dass ein quotierter String in sich auch das Quotierungszeichen enthält ('''Das ist so'ne Sache''').
    Der wird ignoriert, weil das Pattern \w für die Gruppe nicht zutrifft. Ich müsste also in einer negierenden Gruppe die Referenz auf den erkannten Begrenzer nutzen.
    Etwa so: statt '...([\w]+)\1' dann '...([^\1])\1'
    Das ist aber laut RegExp-Syntax nicht machbar.

    Hat jemand eine Idee, wie ich das Pattern verbiegen muß um meine negierte Backreferenz nutzen zu können?
    (Ich bin nicht auf der Suche nach Lösungsvarianten ohne Regexp.)

  • _String_Balanced --> Text zwischen korrespondierenden Klammern

    • BugFix
    • 7. August 2014 um 10:21

    Wobei mir gerade auffällt, dass die Funktion noch nicht narrensicher ist. Sollte im String z.B. eine maskierte schließende Klammer vorhanden sein (als String im String), so wird diese als reguläre schließende Klammer erfasst. Das abzufangen wird aber noch mal gnibbelig, mal schauen.

  • _String_Balanced --> Text zwischen korrespondierenden Klammern

    • BugFix
    • 7. August 2014 um 09:52

    James
    Die Verwendung von Regulären Ausdrücken unter Nutzung der Rekursion ist sicher ein interessanter Ansatz. Aber es ermöglicht immer nur Teillösungen.
    Dass dem so ist ergibt sich auch einfach aus der Tatsache, dass Klammerausdrücke keiner regulären Struktur unterliegen und somit RegExp hier auch schwer anzupassen ist.
    Mal 2 Bsp., was mit Rekursion geht:

    [autoit]


    ;== alles von erster öffnender bis zugehöriger schließender Klammer
    $string = "TEST('Klammer_1': ('Klammer_2': ('Inside_2': ('In_Inside_2': 'value'))),'key_1': ('Klammer_3': ('In_Klammer_3': 'value')),'key_2': ('Klammer_4': 'value')))ENDE"
    $pattern = '(\(([^()]++|(?-2))*\))'
    $a = StringRegExp($string, $pattern, 3)
    ConsoleWrite($a[0] & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    ;== die jeweils am tiefsten verschachtelte Klammer..
    ;== ..für alle Klammerausdrücke einer Ebene
    ;== im Muster sind in einer Ebene: 'Klammer_1', 'key_1', 'key_2'
    $pattern = '\((?:(?(R)\d++|[^()]*+)|(?R))*\)'
    $a= StringRegExp($string, $pattern, 3)
    _ArrayDisplay($a)

    [/autoit]


    Um aber z.B. alle korrespondierenden Klammerausdrücke zu erfassen, muss man dann vom Match die Klammern abschneiden und das Ergebnis wieder parsen usw.
    Ich denke vom internen Zeitaufwand geht das nicht schneller als meine Form der Iteration in der Funktion.

  • Focus auf anderes Control funktioniert, aber Text Cursor immer noch im alten Control

    • BugFix
    • 7. August 2014 um 08:16

    Wenn jetzt noch ein funktionsfähiges Skript dabei wäre, könnte man dir vllt. helfen... :whistling:
    Du bist doch lange genug dabei und weißt, dass wir uns kaum hinsetzen werden und deine Skriptumgebung nachbasteln um dein Problem zu lösen. ;)

  • _String_Balanced --> Text zwischen korrespondierenden Klammern

    • BugFix
    • 6. August 2014 um 15:04

    Ich finde es schade, dass AutoIt keine Möglichkeit bietet Strings zwischen öffnendem und schließendem Zeichen ausbalanciert auszugeben.
    Meine Funktion "_String_Balanced" ermöglicht das.

    Bsp. "Das ist ein Mustertext (hier ist was ich will (plus gekapselten Inhalt) das gehört auch dazu) das hier nicht".
    Hier gibt es zwei Ausdrücke in runden Klammern
    • (hier ist was ich will (plus gekapselten Inhalt) das gehört auch dazu)
    • (plus gekapselten Inhalt)

    Mit meiner Funktion wird der Inhalt von öffnender Klammer bis zugehöriger schließender Klammer ermittelt.
    Alle Klammertypen können verwendet werden '(', '{', '[', '<'. Bei den spitzen Klammern kann zusätzlich ein Tag verwendet werden, praktisch um z.B. Websiten zu parsen.
    Es braucht nur der öffnende Begrenzer (plus optionalem Tag bei spitzen Klammern) angegeben werden. Das Pendant wird automatisch gebildet.
    Weitere Parameter sind
    [optional] Occurence - Welches Vorkommen im String soll gefunden werden. Wie bei StringInStr kann auch von hinten gesucht werden durch negative Zahl.
    [optional] Offset - An welcher Position im String soll begonnen werden.
    Standardmäßig sind Occurence und Offset so gesetzt, dass ein Array mit allen Vorkommen im String zurückgegeben wird. Dabei wird der String von Anfang bis Ende abgegrast.

    Aber mal als Verleich, wie simpel das z.B. mit Lua geht, Variable: text, gesucht ausbalancierter Inhalt in runden Klammern:

    Code
    text = "...."
    ret = text:find('(%b())')

    :whistling:

    _String_Balanced
    [autoit]

    ;===============================================================================
    ; Function Name...: _String_Balanced
    ; Description.....: Ermittelt einen ausbalancierten String innerhalb folgender
    ; ................: Begrenzer: "()", "{}", "[]", "<abc abc>"
    ; ................: Tags bei spitzen Klammern sind optional,
    ; ................: müssen aber für öffnend und schließend identisch sein.
    ; Parameter(s)....: $_sStr String mit begrenztem Substring
    ; ................: $_sOpen Das öffnende Zeichen des Begrenzerpaares und optional der Tag '<bla'
    ; ................: Daraus wird automatisch der schließende Tag gebildet: 'bla>'
    ; .....optional...: $_iOccurence 0 (Standard) Rückgabe aller Funde als Array mit Zähler an [0].
    ; ................: n Beginnt am n-ten Vorkommen von $_sOpen im String.
    ; ................: Negative Werte zählen Vorkommen von rechts.
    ; ................: Occurence greift nur, wenn $_iOffset < 1.
    ; .....optional...: $_iOffset Position im String zum Start der Selektion.
    ; ................: 0 (Standard) Occurence wird verwendet.
    ; Return Value(s).: Erfolg: Der ermittelte String inkl. der Begrenzer.
    ; ................: Fehler: Leerstring @error = 1 $_sOpen beginnt nicht mit '(', '{', '[' oder '<'
    ; ................: @error = 2 $_sOpen nicht in $_sStr enthalten
    ; ................: @error = 3 $_iOccurence größer als Anzahl Begrenzer
    ; Author(s).......: BugFix ( [email='bugfix@autoit.de'][/email] )
    ;===============================================================================
    Func _String_Balanced($_sStr, $_sOpen, $_iOccurence=0, $_iOffset=0)
    If Not StringInStr($_sStr, $_sOpen) Then Return SetError(2, 0, '')
    Local $sTag = ''
    If StringLeft($_sOpen, 1) = '<' Then
    $sTag = StringTrimLeft($_sOpen, 1)
    $_sOpen = '<'
    EndIf
    If Not StringInStr('({[<', $_sOpen) Then Return SetError(1, 0, '')
    StringReplace($_sStr, $_sOpen & $sTag, $_sOpen & $sTag)
    Local $iMax = @extended
    If Abs($_iOccurence) > $iMax Then Return SetError(3, 0, '')
    If $_iOffset < 1 Or $_iOffset = '' Then $_iOffset = 0
    Local $sClose, $sPattern, $fFirst = False, $iLast, $vOut = ''
    Local $countOpen = 0
    If $_iOffset = 0 And $_iOccurence <> 0 Then
    $_iOffset = StringInStr($_sStr, $_sOpen & $sTag, 1, $_iOccurence)
    EndIf
    If $_sOpen = '(' Then
    $sClose = ')'
    Else
    $sClose = Chr(Asc($_sOpen) +2)
    EndIf
    Local $sEscape = ''
    If StringInStr('({[', $_sOpen) Or $sClose = ')' Then $sEscape = '\'
    $sPattern = $sEscape & $_sOpen & $sTag & '|' & $sTag & $sEscape & $sClose
    While 1
    $aMatch = StringRegExp($_sStr, $sPattern, 1, $_iOffset)
    If Not @error Then
    $_iOffset = @extended
    If StringInStr('({[', $aMatch[0]) Or _
    StringInStr('<' & $sTag, $aMatch[0]) Then
    $countOpen += 1
    Else
    $countOpen -= 1
    EndIf
    If Not $fFirst Then
    $iLast = $_iOffset
    $fFirst = True
    ContinueLoop
    EndIf
    $vOut &= StringMid($_sStr, $iLast, $_iOffset-$iLast-1)
    If $countOpen = 0 Then ExitLoop
    $iLast = $_iOffset -1
    Else
    ExitLoop
    EndIf
    Wend
    If $_iOccurence = 0 Then
    Local $n = 2, $match = $vOut, $aOut[2] = [1, $_sOpen & $sTag & $vOut & $sClose]
    While True
    $match = _String_Balanced($_sStr, $_sOpen & $sTag, $n, 0)
    If Not @error Then
    $aOut[0] += 1
    ReDim $aOut[$aOut[0] +1]
    $aOut[$aOut[0]] = $match
    $n += 1
    Else
    Return $aOut
    EndIf
    WEnd
    Else
    Return $_sOpen & $sTag & $vOut & $sClose
    EndIf
    EndFunc ;==>_String_Balanced

    [/autoit]
    Testskript
    [autoit]

    #include '_String_Balanced.au3'
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sHtml = _
    '<div class="content">' & @CRLF & _
    '<ul class="menu">' & @CRLF & _
    '<li class="collapsed first no-dhtml "><li class="BLA"><a href="BLA.html"</a></li><a href="file-management.html" id="dhtml_menu-504">File management</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="session-management.html" id="dhtml_menu-505">Session management</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="editing.html" id="dhtml_menu-508">Editing</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="document-properties.html" id="dhtml_menu-509">Document Properties</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="searching.html" id="dhtml_menu-511">Searching</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="display.html" id="dhtml_menu-510">Display</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml "><a href="macros.html" id="dhtml_menu-512">Macros</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml "><a href="commands.html" id="dhtml_menu-513">Commands</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml "><a href="shortcuts-run-menu.html" id="dhtml_menu-514">Shortcuts for the Run menu</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml active-trail"><a href="windows-dialog.html" id="dhtml_menu-515" class="active">Windows Dialog</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="gui-elements.html" id="dhtml_menu-744">GUI elements</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="switching-between-documents.html" id="dhtml_menu-745">Switching between Documents</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="languages.html" id="dhtml_menu-746">Languages</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="settings.html" id="dhtml_menu-747">Settings</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml "><a href="plugins.html" id="dhtml_menu-749">Plugins</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml "><a href="command-line.html" id="dhtml_menu-750">Command Line</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml "><a href="control-files.html" id="dhtml_menu-751">Control files</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml "><a href="shell-extension.html" id="dhtml_menu-752">Shell Extension</a></li>' & @CRLF & _
    '<li class="collapsed no-dhtml "><a href="further-help.html" id="dhtml_menu-748">Further help</a></li>' & @CRLF & _
    '<li class="leaf no-dhtml "><a href="upgrading.html" id="dhtml_menu-753">Upgrading</a></li>' & @CRLF & _
    '<li class="leaf last no-dhtml "><a href="credits.html" id="dhtml_menu-754">Credits</a></li>' & @CRLF & _
    '</ul>' & @CRLF & _
    '</div>' & @CRLF

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, 'Test-html', 'Alle Treffer als Array')
    $ret = _String_Balanced($sHtml, '<li')
    _ArrayDisplay($ret)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, 'Test-html', '5.tes Vorkommen -> Konsole')
    $ret = _String_Balanced($sHtml, '<li', 5)
    ConsoleWrite($ret & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, 'Test-String mit "{"', 'Alle Treffer als Array')
    $string = "TEST{'Klammer_1': {'Klammer_2': {'Inside_2': 'value'}},'key': {'Klammer_3': 'value'}}ENDE"
    $ret = _String_Balanced($string, '{')
    _ArrayDisplay($ret)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, 'Test-String mit "("', 'Alle Treffer als Array')
    $string = "Das ist ein Mustertext (hier ist was ich will (plus gekapselten Inhalt) das gehört auch dazu) das hier nicht"
    $ret = _String_Balanced($string, '(')
    _ArrayDisplay($ret)

    [/autoit]

    Dateien

    _String_Balanced.au3 3,63 kB – 262 Downloads

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™