Seite 1 von 2

Verfasst: Mittwoch 24. November 2004, 09:55
von jens
Also bei allen Experimenten, scheit mir die Lösung hier:
http://python.sandtner.org/viewtopic.php?p=12502#12502
noch am besten zu sein ;)

Naja, ich hab sie mal mit neuen Erkenntnissen ausgestattet:

Code: Alles auswählen

def gefFileInfo( FileName ):
    def getInfo( InfoStr ):
        return re.findall( InfoStr+"(.+)\x01", RAWdata )[0][:-2]

    FileHandle = open( FileName, "rb" )
    RAWdata = FileHandle.read().replace("\x00","")
    FileHandle.close()

    POS = RAWdata.rfind( "StringFileInfo" )

    if POS == -1:
        print "* NOT FOUND *"
        return

    EndPOS = RAWdata.rfind( "VarFileInfo" )
    if EndPOS == -1:
        EndPOS = POS+500

    RAWdata = RAWdata[ POS:EndPOS]

    print getInfo( "CompanyName" )
    print getInfo( "FileDescription" )
    print getInfo( "FileVersion" )
    print getInfo( "InternalName" )
Leider versagt aber bei re.findall( InfoStr+"(.+)\x01", RAWdata ) die "suche" nach \x01

@dookie: Du hattes irgdnwo mal \0x01 geschrieben... Warum?

Verfasst: Mittwoch 24. November 2004, 11:38
von Dookie
@dookie: Du hattes irgdnwo mal \0x01 geschrieben... Warum?
War wohl ein Tippfehler :)


Gruß

Dookie

Verfasst: Mittwoch 24. November 2004, 17:46
von jens
Und ich dachte schon, es wäre eine andere Schreibform oder so...

Aber wie erklärt es sich, das re.findall( InfoStr+"(.+)\x01", RAWdata ) nicht bei \x01 "aufhöhrt" ???
Das Ergebnis ist immer ab dem InfoStr bis zum ende... Obwohl da halt ein \x01 kommt...

Kommt RE mit Sonderzeichen nicht zurecht?

EDIT: Anscheinend, denn das hier funktioniert:

Code: Alles auswählen

        RAWdata = RAWdata.replace("\x01","\n")
        return re.findall( InfoStr+"(.+)\n", RAWdata )[0][:-2]

Verfasst: Mittwoch 24. November 2004, 17:53
von Milan
Hi. Vielleicht ist ja das letzte zZeichen ein \x01, denn du hast ja im greedy mode gesucht :wink:

Verfasst: Mittwoch 24. November 2004, 17:56
von Dookie
versuchs mal so
re.findall( InfoStr+"([^\x01]+)", RAWdata )

Dookie

Verfasst: Mittwoch 24. November 2004, 17:58
von jens
Jep, das geht... Wieso?

Verfasst: Mittwoch 24. November 2004, 18:29
von Milan
Hi. Auch \x01 ist ein beliebiges Zeichen und wird durch den Punkt "." repräsentiert und soll beliebig oft vorkommen. Aus der Docu:
*?, +?, ??
The "*", "+", and "?" qualifiers are all greedy; they match as much text as possible. Sometimes this behaviour isn't desired; if the RE <.*> is matched against '<H1>title</H1>', it will match the entire string, and not just '<H1>'. Adding "?" after the qualifier makes it perform the match in non-greedy or minimal fashion; as few characters as possible will be matched. Using .*? in the previous expression will match only '<H1>'.
Außerdem ist ein Punkt kein "\n". Das heißt, er sucht bei dir maximal eine Zeile raus, mehr nicht.

Verfasst: Mittwoch 24. November 2004, 18:48
von jens
Das macht es jetzt ein wenige klarer... Somit macht es eigentlich immer Sinn ein "?" zu benutzen...

Nun gut, re.findall( InfoStr+"(.+?)\x01", RAWdata ) klappt nun auch, es ist sogar besser als die "([^\x01]+)" Variante...
Denn ich hab festgestellt, das in seltenen Fällen es leider doch kein \x01 gibt:
z.b.: für folgende Windows-Dateien:
C:\windows\twain.dll - (Twain-Source-Manager)
C:\windows\AppPatch\AcLayers.dll - (Windows Compatibility DLL)

mit der Such mittels "(.+?)\x01" fällt twain.dll schon mal raus... Bei der anderen Datei kommen allerdings fehlerhafte Ergebnisse zurück :(

Verfasst: Mittwoch 24. November 2004, 19:37
von Milan
Hi. Das würde ich nicht so sehen, denn wie gesagt, sobald ein "\n" vorkommt, versagt deine Variante, wenn du nicht im DOT-ALL modus bist (Da ist der "." auch ein "\n"). Mach lieber das:

Code: Alles auswählen

muster=re.compile(InfoStr+"([^\x01]+)\x01")
#oder bei dir (trotzdem net so gut, non-greedy):
#muster=re.compile(InfoStr+"(.+?)\x01",re.DOTALL)
muster.findall( RAWdata )

Verfasst: Mittwoch 24. November 2004, 19:57
von jens
Milan hat geschrieben:sobald ein "\n" vorkommt, versagt deine Variante
Da hast du eigentlich recht... Allerdings zeigt sich jedoch, das "(.+?)\x01" besser klappt... Zumindest habe ich bisher nichts gegenteilige feststellen können...

Doch ich würde es ehr vorziehen A-Za-z0-9 usw. zu nehmen, also wirklich nur Zeichen die vorkommen dürfen, allerdings funktioniert es leider nicht... Es kommen nie Treffer zu stande bei:
re.findall( InfoStr+"([a-zA-Z0-9_]+)\x01", RAWdata )

Verfasst: Mittwoch 24. November 2004, 20:06
von Dookie
noch nen versuch:
re.findall(InfoStr+"([a-zA-Z0-9_\x00]+)\x01", RAWdata)
oder
re.findall(InfoStr+"([\w\x00]+)\x01", RAWdata)
eventuell, falls auch Leerzeichen und Linefeeds vorkommen
re.findall(InfoStr+"([\w\x00\x20\r\n]+)\x01", RAWdata)


Gruß

Dookie

PS.: jetzt weiss ich woher das \0x01 kam, mit 0x01 wird in Python eine Hexadezimalzahl direkt im Code geschrieben. :)

Verfasst: Mittwoch 24. November 2004, 20:10
von jens
Alle drei Varianten funktionieren leider nicht... es wird nie etwas gefunden...

Hab das Listing, mit Beispielanwendung mal hier gepostet:
http://python.sandtner.org/viewtopic.php?p=12561