Daten zwischen 2 Zeichen auslesen - Denkanstoss

  • Hallo Forum,

    benötige für ein Programm einen kleinen Denkanstoss zur Umsetzung. Programmieren versuch ichs dann alleine :)

    Also zum eigentlichen Thema: Ich möchte aus einer Datei Daten auslesen und in eine Excel Tabelle oder Datenbank schreiben.

    Zur Textdatei: In dieser befindet sich folgendes

    <Value1 Key1><Value2 Key2><Value3 Key3>etc. etc.

    Das ganze läuft bis zu 50 mal in einer Zeile und dann noch 150 Zeilen runter.

    Also alle Werte zwischen "<>" müssen gespeichert werden und der Wert ist immer durch Leerzeichen getrennt. Simpler Aufbau, aber an der Umsetzung scheitert es.

    Wie würdet ihr das ganze angehen? Mein erster Gedanke: File öffnen, erste Zeile einlesen, erstes Zeichen einlesen, Zeichen für Zeichen einlesen bis ">", dann StringSplit und beide Werte abspeichern, nächstes Zeichen einlesen, Loop Schleife bis ">" und so weiter und so fort. Nur denke ich mal dass das nicht ganz der Lösungsansatz ist, Zeichen für Zeichen einzulesen. :/ :/ :/ :/

    mfG

    JoGi

  • Beipiel einer Funktion, die jeweils eine Zeile bearbeitet und dann in einem 2D Array jeweils Value und Key zurückgibt. Den EInbau in eine Funktion um die 150 Zeilen zu bearbeiten überlasse ich Dir.

  • Meine Lösung wäre diese:

    Also erst per Regex separieren und dann nochmal aufsplitten.

    Wegen der Datei: Les die datei doch in ein array mit FileReadToArray und dann jede einzelne Zeile an die Funktion übergeben oder falls du nachher alle in einem Array brauchst, erst mal die Zeilen aneinander hängen (also einen String draus machen) und dann an die Funktion übergeben.

    Einmal editiert, zuletzt von Moombas (24. November 2023 um 11:37)

  • AutoIt
    #include <array.au3>
    #include <String.au3>
    $source = '<Value1 Key1><Value2 Key2><Value3 Key3>'&@CRLF&'<Value1 Key4><Value5 Key5><Value6 Key6>'
    
    
    $a = _stringbetween($source, "<", ">")
    
    
    _ArrayDisplay($a)


    Einfacher geht's nicht.


    wenn es keine anderen Einflüsse gibt dann sollte _stringbetween immer funktionieren.

  • Moombas

    nunja entweder habe ich die frage nicht richtig gelesen oder verstanden.

    Verstanden habe ich es so :

    Wie bekomme ich die Werte zwischen '<''>' heraus.
    Der Ersteller hat geschrieben das die Werte innerhalb mit einem Leerzeichen getrennt sind.
    Wo nachmeiner Einschätzung der Ersteller denkt das hätte Auswirkungen auf den Code.
    Das Leerzeichen hat aber keine Auswirkung auf das Ergebnis.

    Denn er hat nicht gesagt er möchte alle werte zwischen '<''>' & diese nochmal im Leerzeichen splitten um statt 1 Wert 2 Werte zu erhalten.


    ob nun da steht : <ABC BLA BLA BLA>, oder <ABCBLABLABLA> ist egal es ist und bleibt 1 Wert zwischen <>.
    ob zwischen in meinem Beispiel ein Leerzeichen ist, ist unerheblich , da es nicht berücksichtigt werden muss.

    Außer der Ersteller hat die Absicht die Werte nochmal auseinander zu nehmen.

    Dann hast du natürlich vollkommen recht.

  • Denn er hat nicht gesagt er möchte alle werte zwischen '<''>' & diese nochmal im Leerzeichen splitten um statt 1 Wert 2 Werte zu erhalten.

    Leider ist es aber genauso. Hab mich da wohl doof ausgedrückt.

    Aber trotzdem Danke für die Denkhilfe.

    Les die datei doch in ein array mit FileReadToArray


    Danke an alle die da Vorschläge gemacht haben. Im Prinzip hätte ich ja nur den Denkanstoss benötigt, das da gleich Vorschläge gepostet werden, damit hätt ich nicht gerechnet.


    :thumbup: :thumbup: :thumbup: :thumbup: :thumbup: :thumbup: :thumbup: :party: :party: :party: :party: :party: :party: :klatschen: :klatschen: :klatschen: :klatschen: :klatschen: :klatschen:

  • Hallo miteinander,

    es gibt die Möglichkeit mittels FileReadToArray, die Datei einzulesen und jede Zeile anzeigen zu lassen (In MsgBox, als String etc.)

    Aber: Funktioniert das irgendwie dass ich die ausgelesene Zeile mittels StringRegExp (konkret <> die beiden Zeichen) prüfe UND denn Inhalt der ausgelesenen Zeile wieder in einem Array zurückgeben lasse?

    Also in etwa so:

    Die Datei besteht ja nur aus:

    <Value1 Key1><Value2 Key2><Value3 Key3>

    <Key1 Value><Key1 Value><Key1 Value><Key1 Value><Key1 Value><Key1 Value>

    <Key1 Value>

    <Key1 Value><Key1 Value><Key1 Value><Key1 Value><Key1 Value>

    <Key1 Value><Key1 Value><Key1 Value><Key1 Value>

    <Key1 Value><Key1 Value><Key1 Value><Key1 Value>

    Also ich lese Zeile 1 aus:

    <Value1 Key1><Value2 Key2><Value3 Key3>

    Mittels RegEx oder sonstigem Befehl alles zwischen <> auslesen

    und Rückgabe in Array

    value1 key1

    value2 key2

    value3 key3

    Danke, LG

    Einmal editiert, zuletzt von JoGi (27. November 2023 um 00:08)

  • Warum ist in der ersten Zeile im Vergleich zu den anderen Key und Value vertauscht?

    Ansonsten verstehe ich das aus dem Kontext so, dass du zeileweise durchgehen möchtest und für jede Zeile einzeln ein Array haben möchtest mit allen Key-Value Paaren, welche auch noch getrennt werden sollen.
    Richtig?

    Mein Vorschlag:

    Man kann genauso auch ein Array für alle Paare in der Datei machen anstatt zeilenweise durchzugehen aber wir kennen den tatsächlichen Anwendungsfall ja nicht.

  • Bin ich jetzt deppert? Genau das macht mein Vorchlag doch schon -.-

    Allerdings habe ich beachtet das in der ersten Zeile das falsch herum steht, wie du es angegeben hast (<Value1 Key1>) und nicht was man erwarten würde (<Key1 Value>) und natürlich das mit dem Filereadtoarray noch nicht eingebaut. Unten mal der angepasste code

    Einmal editiert, zuletzt von Moombas (27. November 2023 um 13:47)

  • Also ich sag mal so:

    Nach der Arbeit bis in die Nacht hinein zu programmieren, bzw. sinnerfassend lesen ist dann schon schwer :rtfm:


    Spoiler anzeigen

    Also danke mal an alle die mir da weitergeholfen haben.

    Musste umswitchen da die riesige Textdatei doch nicht nur <value key> enthielt. Dank sei Notepad++.

    Gewisse Zeilen lauten <3098 43><10987 52/><874 3><1 1><5 2> --> daher der Gedanke, alles zwischen <> auslesen und das Leerzeichen als Trenner, fertig.

    Dann wieder folgende Zeilen <10985 "Text"/><group 5>< group 6 stop 578>< model 8=9> teils mit vorangestellten Leerzeichen etc.

    Ich habe es jetzt wirklich notgedrungen so gelöst dass ich mittels FileReadLine einlese.

    Mittels Stringbetween <> eingrenze und den String danach durch eine Routine laufen lassen muss.

    Was um diese Uhrzeit nicht meine Stärke ist --> der Befehl StringRegExp ist böse, sehr böse.

    Momentan schaffe ich es nicht mal den String nach folgenden Kriterien zu durchsuchen:

    String enthält ein "=" Zeichen

    String enthält "stop"

    String enthält "iy"

    String enthält "group"


    Momentan ist es Learning by Doing :Glaskugel:

  • Ich denke es wäre jetzt mal Zeit wirklich ganz konkrete Auszüge der Datei zu zeigen und ganz konkret zu sagen was davon in welcher Form gebraucht wird.
    Abstrakte Beispiele decken deinen Sachverhalt ganz offensichtlich nicht hinreichend ab.
    Noch besser wäre den Hintergrund zu erfahren: Was sind das für Daten, wo kommen die her und wofür genau werden die gebraucht?
    Auf die Art bisher können wir dir halt nur bedingt helfen, da wir das ganze Ausmaß überhaupt nicht kennen und somit zwangsläufig nur ungenügende Lösungen anbieten können.

    Momentan schaffe ich es nicht mal den String nach folgenden Kriterien zu durchsuchen:
    String enthält ein "=" Zeichen
    String enthält "stop"
    String enthält "iy"
    String enthält "group"

    Möglicher Grundaufbau (kann wie gesagt nur vom Geschriebenen ausgehen):

    AutoIt
    If StringInStr($sString, '=') Then
    	; irgendwas machen
    ElseIf StringInStr($sString, 'stop') Then
    		; irgendwas machen
    ElseIf StringInStr($sString, 'iy') Then
    		; irgendwas machen
    ElseIf StringInStr($sString, 'group') Then
    		; irgendwas machen
    EndIf

    Was um diese Uhrzeit nicht meine Stärke ist --> der Befehl StringRegExp ist böse, sehr böse.

    Das ist verständlich, da reguläre Ausdrücke halt tatsächlich erst einmal eine Einarbeitungszeit benötigen.
    Aus dem Stand wird man hiermit nicht arbeiten können - ein Ding der Unmöglichkeit.
    Hier im Forum hat ein User aber mal ein gutes Tutorial dazu geschrieben: >>StringRegExp Tutorial<<

  • Du wirst es zwar nicht glauben aber ihr habt mir mehr als genug geholfen.

    Das StringInStr funktioniert wunderbar.

    Es handelt sich um eine Datensicherung, die Werte lese ich aus und schreib sie mir in eine csv.Datei.

    Und da es die gleiche Maschine desöfteren gibt, kann ich mittels dieser csv.Dateien eine Excel Tabelle erstellen mit denen ich dann Vergleiche anstellen kann (verschiedene Parameter und Einstellungen)

    Ja ich weiss dass es die Möglichkeit gibt gleich in Excel reinzuschreiben aber so fit bin ich dann doch nicht.

    Es funktioniert alles wunderbar. Ich bekomme die Datei eingelesen, jeden String aufgelöst und gespeichert.

    Bei einigen Sachen musste ich halt um die Ecke denken, aber für mich passt´s so.

    Hätte da allerdings eine letzte Frage für eine Aufgabe die ich, meiner Meinung nach umständlich gelöst habe:

    Folgende(r) String(s):

    8009 635

    8008 "text 2"

    8050 639 2

    Der erste geht ja super klar mit StringSpit aufzulösen (Trenner "Leerzeichen" und hab dann demenstprechend 2 Werte in nem Array.

    Der zweite und dritte String gibt 3 Werte in nem Array zurück. Gibts ne Flag oder Option oder Befehl um den Trenner nur einmalig anzuwenden?

  • Gibts ne Flag oder Option oder Befehl um den Trenner nur einmalig anzuwenden?

    Bei StringSplit direkt nicht. Daher müsstest du dir das entsprechend anders basteln.
    StringRegExp lassen wir ja erstmal außen vor. Stattdessen können wir uns zu Nutze machen, das StringInStr die Position des Fundes im String zurückgibt.
    Damit haben wir alle Infos um den String entsprechend zu zerlegen:

    AutoIt
    $sString = '8050 639 2'
    
    $sLinks = StringLeft($sString, StringInStr($sString, ' ') - 1)
    $sRechts = StringTrimLeft($sString, StringInStr($sString, ' '))
    
    ConsoleWrite($sLinks & @CRLF & $sRechts & @CRLF)


    Wenn du dann irgendwann dich doch Richtung reguläre Ausdrücke orientieren möchtest, dann kannst du das damit kürzer und zielgerichteter implementieren.
    Folgendes z.B. trennt nur am ersten Leerzeichen und entfernt auch gleich die Anführungszeichen falls welche da sind:

    AutoIt
    #include "Array.au3"
    
    $sString = '<8008 "text 2">'
    $aSplit = StringRegExp($sString, '<(\H+)\h"?(.+?)"?>', 3)
    _ArrayDisplay($aSplit) 

    Einmal editiert, zuletzt von AspirinJunkie (29. November 2023 um 08:01)

  • Wenn du dann irgendwann dich doch Richtung reguläre Ausdrücke orientieren möchtest

    Ich "programmiere" seit ca.10 Jahren ab und zu kleine Programme mit AutoIT.

    Zum Datensichern, Ping Abfragen über GUI mit Farbanzeige etc. Und da tu ich mir schon schwer. Also ich denke nicht dass ich mit StringRegExp einen grossen Wurf mache.

    Aber danke für den Hinweis.


    Beziehungsweise danke für DIE Hinweise

    :klatschen:

    Einmal editiert, zuletzt von JoGi (1. Dezember 2023 um 01:04)