Information aus dokument extrahieren

  • Ich will mich an ein etwas komplizierteres "programm" wagen udn stehe nun vor einem Problem

    ich brauche eine funktion, die eine bestimmte stelle einer textdatei wiedergibt, die von einem anderen Programm erzeugt wird.
    das problem ist nun, das diese datei nicht gleichartig erzeugt wird, also nicht zeile x buchstabe y bis z ausgelesen werden soll, sondern der inhalt zwischen 2 bestimmten zeichenfolgen, zB:

    VariableA=... VariableB=... VariableC= ...

    nun sollen die variablen b und c ausgelesen werden, je nach länge des inhalts von a verschiebt sich aber natürlich die position.
    Also muss die Funktion erkenne, dass variable b nach "VariableB=" anfängt und vor " VariableC" endet - ist das möglich?

  • ein teil der rückgabedatei ist

    try=75 pos=14 neg=61

    in diesem fall brauche ich den 2. wert (pos) und den 3. Wert (neg)

    hintergrund: die beiden Werte braucht ein anderes Programm, da as script quasi als übergeordnete instanz arbeiten soll

  • Jupp, sollte wirklich kein Problem sein. Versuch mal folgendes:

    [autoit]

    #NoTrayIcon
    #include <String.au3>
    Opt("MustDeclareVars", 1)

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

    Local Const $S_TXTFILE = @ScriptDir & "\textfile.log"
    Local $h_file = -1
    Local $s_filecontent, $s_variableb, $s_variablec = ""

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

    $h_file = FileOpen($S_TXTFILE, 0)
    If $h_file == -1 Then
    MsgBox(48, "Warning", "The file can not be opened!")
    Exit(2)
    EndIf
    While 1
    $s_filecontent &= FileRead($h_file)
    If @error = -1 Then
    ExitLoop 1
    EndIf
    WEnd

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

    If $s_filecontent == "" Then
    MsgBox(48, "Warning", "The file is empty!")
    Exit(1)
    EndIf

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

    $s_variableb = _StringBetween($s_filecontent, "pos=", " neg")
    $s_variablec = _StringBetween($s_filecontent, "neg=", " ")
    If IsArray($s_variableb) == 1 And IsArray($s_variablec) == 1 Then
    MsgBox(0, "Debug", "ValB: " & $s_variableb[0] & @CR & "ValC: " & $s_variablec[0])
    EndIf

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

    Exit(0)

    [/autoit]

    Beim 2. StringBetween musst Du eventuell ein wenig tricksen, bzw. mit StringInStr und Konsorten arbeiten.

    Einmal editiert, zuletzt von teh_hahn (21. Mai 2007 um 18:23)

  • ok das muss ich erstmal lesen und verstehen ^^ - danke ich schaus mir mal an

    • Offizieller Beitrag

    Hi,

    ich würde sowas anpassen an deine Bedürfnisse:

    Spoiler anzeigen
    [autoit]

    Global $wortdavor = ''
    Global $found = StringRegExp(FileRead(FileOpen(@ScriptDir & '\log.txt', 0)), '(?<=' & $wortdavor &')\w{1,}', 3)
    If IsArray($found) Then
    For $i = 0 To UBound($found) - 1
    MsgBox(64, 'Found', $found[$i])
    Next
    EndIf

    [/autoit]

    So long,

    Mega

  • OK, ich geb mich geschlagen...
    th.megers Lösung ist auf jeden Fall eleganter! Habs Dir mal zusammen gefasst. Viel Spaß noch!

    [autoit]

    #NoTrayIcon
    Opt("MustDeclareVars", 1)

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

    Local Const $S_TXTFILE = @ScriptDir & "\textfile.log"
    Local $h_file, $a_found = -1
    Local $s_filecontent, $s_variableb, $s_variablec = ""
    Local $a_searchstrings[2] = ["pos=", "neg="]

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

    $h_file = FileOpen($S_TXTFILE, 0)
    If $h_file == -1 Then
    MsgBox(48, "Warning", "The file can not be opened!")
    Exit (2)
    EndIf

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

    While 1
    $s_filecontent &= FileRead($h_file)
    If @error = -1 Then
    ExitLoop 1
    EndIf
    WEnd

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

    If $s_filecontent == "" Then
    MsgBox(48, "Warning", "The file is empty!")
    Exit (1)
    EndIf

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

    For $i = 0 To UBound($a_searchstrings, 1) - 1 Step 1
    $a_found = StringRegExp($s_filecontent, '(?<=' & $a_searchstrings[$i] & ')\w{1,}', 3)
    If IsArray($a_found) == 1 Then
    For $p = 0 To UBound($a_found) - 1
    MsgBox(0, "Debug", $a_found[$p])
    Next
    EndIf
    Next

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

    Exit (0)

    [/autoit]

    Gefixed...

    Einmal editiert, zuletzt von teh_hahn (21. Mai 2007 um 19:48)

  • jetzt hatte ich gerade die 1. version verstanden da kommst du mit RegExp an ^^

    erstmal zur alten fassung, dann schau ich mir die neue an :D;

    also:
    Der pfad wird hinterlegt, ein handle für das file erzeugt sowie variablen für die aktuelle zeile und die zu suchenden variablen
    das textfile wird "in den handle" geöffnet, leere und nicht vorhandene Datei abgefangen
    Bei jedem fileread wird die nächste zeile aufgerufen und an filecontent angehängt, bis ein fehler auftritt (zwangsläufig ende der Datei (abgesehen von fehlerhaften dateisystem/Datenträger))
    die beiden zeilen gehen den string durch bis die passende stelle erreicht ist

    Der letzte Part gibt ja eine meldung aus, wenn beide variablen vorhanden sind (da string= array of char)

    Fragen:

    1)
    dann hängt die ganze Datei also in einem string. - soweit ich das weiß, hat aber eine variable eines bestimmten typs auch eine bestimmte größe, oder ist das nur in Pascal so?

    2)
    Die verschiedenen Parameter für Exit (0 1 und 2) sind dazu da, um feststellen zu können, wo beendet wurde bzw welcher Fehler aufgetreten ist?

    3)
    == entspricht dem pascal = und = dem pascal :=??
    das würde auch ein problem mit einem anderen script erklären *VorDenKopfHau*

    4)
    aus der hilfe:
    While 1
    $chars = FileRead($file, 1)
    If @error = -1 Then ExitLoop
    MsgBox(0, "Char read:", $chars)
    Wend
    -> dabei wird doch der erste buchstabe der letzten zeile ausgegeben und nicht wie es da steht, der 1. jeder zeile, da es eine zuweisung ist ein keine ergänzung (&=)??

    PS: ich hatte schon angst, die chars einzeln abfragen zu müssen (if char (0)= n then if char (1)=e usw)

    Achja und sorry für die vielen Fargen aber ich will gerne lernen :D

    3 Mal editiert, zuletzt von CallMeN00b68 (21. Mai 2007 um 19:48)

  • Hi. Werd mal versuchen Deine Fragen so gut wie möglich zu beantworten...

    1. Soweit ich weiß, gibt es eine maximale Länge für Strings (schaust am besten mal in die aktuelle Hilfe...) Wenn Deine Datei also zu lang ist, musst du aud die Länge des Strings prüfen und dann den Rest der Datei in eine neue Variable schreiben (usw...)

    2. Ja, die Exits in AutoIt gleichen dem ERRORLEVEL der Windows Batch. Somit könnte man nacher abfangen, ob das Programm korrekt beendet wurder (ERRORLEVEL = 0) oder nicht. Ist Geschmackssache. Ich mach es ganz gerne...

    3. Hab mich bisher nicht mit Pascal beschäftigt, aber in AutoIt ist es einfach so, dass das "=" sowohl Zuweisung als auch Überprüfung in If/Case-Anweisungen ist (eigentlich sehr schweinisch...) Das "==" überprüft auch Groß/Kleinschreibung (case-sensitive). Ich finds so einfach besser. Ebenfalls Geschmackssache...

    4. Nein, dabei wird immer ein Zeichen ausgegeben, bis das Dateiende (EOF) erreicht ist. Der zweite Parameter ($i_count) von FileRead bewirkt dies.

    Fragen kost' ja nix und wenn ich keine Lust hätte Dir zu antworten, dann würd ichs einfach lassen. ;) Also np...

  • 4. Nein, dabei wird immer ein Zeichen ausgegeben, bis das Dateiende (EOF) erreicht ist. Der zweite Parameter ($i_count) von FileRead bewirkt dies.
    -> ja das schon, aber der variable $chars wird ja jeweils nur der aktuelle wert zugewiesen (der alte überschrieben), du hast oben "&=" verwendet - wozu, wenn = das gleiche bringen würde?!

    kurz schonmal zum neuen - ich sehe nicht, dass dort das ende abgefragt wird, enstprechend dürfte es ein problem geben,oder? (das leerzeichen vor neg müsste mit eingelesen werden soweit ich das verstehe)

    edit:

    also vom neuen teil verstehe ich jetzt keine zeile, allein schon weil ich keine RegExp kann - aber soweit ich es sehe, kommt als ergebnis nur a_found heraus, also 1 variable, nicht 2

    edit 2: Aus der Hilfe:

    Die maximale Zeichfolgelänge ist 2147483647 Zeichen (denke aber dran, dass keine Zeile in einem AutoIT Skript 4095 Zeichen überschreiten kann.)

    -> bedeutet das, dass, wenn der string 4090 zeichen hat, die zeile

    if $string == "hallo" then

    schon zu lang wäre?

    2147483647 Zeichen wären ja 2GB und das reich allemal, bei knappen 4 kb (4095 zeichen) wird es jedoch eng

    2 Mal editiert, zuletzt von CallMeN00b68 (21. Mai 2007 um 19:58)

  • " $a &= 'x' " bedeutet dasselbe wie: " $a = $a & 'x' "

    ja das ist mir klar, aber in dem text aus der Hilfe steht ja
    $chars = FileRead($file, 1)
    und nicht
    $chars = $chars & FileRead($file, 1)

    $a_found ist ein Array (Prüfung: If IsArray($a_found) == 1 Then ).
    Dort sind alle gefundenen Elemente enthalten

    achso ok - bin durcheinander gekommen, weil ja string auch ein array of char ist

    Einmal editiert, zuletzt von CallMeN00b68 (21. Mai 2007 um 20:06)

  • Achso, dann habe ich Deine Frage falsch verstanden.

    Also, beim Hilfe Beispiel wird solange EIN Zeichen ausgegeben, bis das Ende der Datei erreicht ist. die Variable $chars wird in der While-Schleife jedesmal aufs neue überschrieben, richtig. Wenn Du dir die Variable $chars nach der While-Schleife anschauen würdest, so hättest Du nur das letzte Zeichen der Datei darin stehen.

    Was meinst Du mit dem Ende? Die Searchstrings musst Du gegebenenfalls oben anpassen, wobei ich jetzt aber kein problem mit einem Leerzeichen sehe. Ansonsten einfach

    [autoit]

    Local $a_searchstrings[2] = ["pos=", "neg="]

    [/autoit]

    anpassen...

    Wegen des StringRegExp fragst Du am besten th.meger... Da bin ich jetzt nicht soo bewannt...

  • also ich probiers erstmal nach deiner methode (aber nicht jetzt, verlasse erstmal den PC :D)

    danke soweit ersteinmal, wäre toll wenn noch ne antwort wegen der stringlänge kommen würde (wie die zahl zu verstehen ist mit 4kb langen zeilen)

    ansonsten noch einen schönen abend

  • Die 4.095 (also MAX_LINESIZE) ist die Anzahl der Zeichen, die eine AutoIt-Zeile lang sein darf (wie z.B. eine If-Abfrage)

    Die Länge eines Strings in Autoit beträgt angeblich 2.147.483.647 (entspricht 256 Megabyte) Zeichen, was ich aber nicht weiter kommentieren kann (solche großen Datenmengen würde ich nicht mit AutoIt verarbeiten).

    Hoffe ich konnt Die helfen.

    Schönen abend ebenfalls!

    PS: Die Länge einer Skriptzeile beträgt ca 0.5 Kilobyte, nicht 4KB!

    Einmal editiert, zuletzt von teh_hahn (21. Mai 2007 um 20:55)

    • Offizieller Beitrag

    Hallo!

    Ich weiß ja nicht wie Du rechnest aber 2.147.483.647 Zeichen entsprechen 2.147.483.647 Byte das sind nach Adam Riese gerundet 2 Gigabyte und nicht 256 Megabyte. Genau sind es 1,999999999068677425384521484375 Gigabyte oder 2 Gigabyte - 1 Byte


    PS: MAX_LINESIZE sind 4095 Zeichen = 4095 Byte das sind gerundet 4 Kilobyte, genau sind es 3,9990234375 Kilobyte oder 4 Kilobyte - 1 Byte!

    • Offizieller Beitrag

    Hi!

    Bernd: Er hat immer noch aus Bits in Bytes umgerechnet, was aber wie du schreibst unnötig sein dürfte.
    Wobei es bei Unicode ja jetzt 16 Bits pro Zeichen sein müssten statt 8 Bits. Demnach müssten es entweder max 4 GB sein oder (was ich eher glaube) wegen der Dateigrößenbeschränkung unter Win98 usw. nur halb so viele Zeichen sein, oder irre ich mich da?

    peethebee