Seite 1 von 1

"format/muster" erkennung! ?? (anfaengerfrage)

Verfasst: Dienstag 23. Oktober 2007, 12:06
von mulder
moin!

soo ich bin noch anfaengr im pythonieren! :lol:

ich schreibe gerade nen script das muesste aus einer "infoausgabe" alles "rausfiltern" das das muster

"eigenschafts name": "eigenschalft"

hat ..

wobei der name auch leerzeichen enthalten kann.


ich habs shcon mit re.search() versucht .... aber irgendwie haenge ich gerade! :oops:

eigentlich brauche ich nur etwas nach dem (anfaenger) muster

Code: Alles auswählen

if ZEILE.format(%s + ':' + %s)
    array.apend(ZEILE)

naja .

danke!

Verfasst: Dienstag 23. Oktober 2007, 12:13
von Rebecca
Dein Stichwort heisst "Regular Expressions", dazu gibt es in Python das Modul re. Ein Beispiel fuer deinen Fall:

Code: Alles auswählen

>>> import re
>>> s = '"eigenschafts name": "eigenschalft"'
>>> PATTERN = r'"(.*?)": "(.*?)"'
>>> re.findall(PATTERN, s)
[('eigenschafts name', 'eigenschalft')]

Verfasst: Dienstag 23. Oktober 2007, 12:18
von mulder
danke .... bin ich auch schon drauf gestossen und habe aber mit "re.search()" rumexperimentiert! und nicht den richtigen "ausdruck" gefunden!

:oops:

zur erklaerung fuer mich! ..

die "(.*?)" stehn fuer "irgend ein string" ?

Verfasst: Dienstag 23. Oktober 2007, 12:27
von keppla
mulder hat geschrieben:die "(.*?)" stehn fuer "irgend ein string" ?
. steht für ein beliebiges zeichen
* steht für 0 oder mehr zeichen
? für "so wenig wie möglich", damit "jedes zeichen" nicht den doppelpunkt mitmatched.
Die Klammern stehen für Gruppen.

Genauer stehts hier: http://docs.python.org/lib/re-syntax.html

Verfasst: Dienstag 23. Oktober 2007, 12:39
von Rebecca
Die runden Klammern geben Gruppen an. Das hat nichts damit zu tun, was gefunden wird, sondern beeinflusst nur, wie du es zurueckbekommst: Du bekommst fuer jeden Match ein Tupel mit allen Gruppen zurueck. Ohne die Gruppen wuerdest du den gesamten Match in einem String zurueckbekommen:

Code: Alles auswählen

>>> PATTERN = r'".*?": ".*?"'
>>> re.findall(PATTERN, s)
['"eigenschafts name": "eigenschalft"']
Der Punkt steht fuer ein beliebiges Zeichen (ohne Zeilenumbruch). Der Stern dahinter ist eine "Mengenangabe" und sagt, dass dieses Zeichen null mal bis beliebig oft vorkommen darf. Das Fragezeichen steht fuer non-greedy, d.h. es wird der kleinstmoegliche Match gewaehlt und nicht wie sonst der groesstmoegliche.

EDIT: upps, kepplas post uebersehen...

Verfasst: Mittwoch 24. Oktober 2007, 07:30
von mulder
DANKE! ... :P

ich musste zwar noch das '?' rausnehmen ... weil es den zeilenumbruch ignoriert hat! ... aber dadurch lernt man nur dazu! 8)

mulder ...

Verfasst: Mittwoch 24. Oktober 2007, 12:10
von HWK
mulder hat geschrieben:DANKE! ... :P

ich musste zwar noch das '?' rausnehmen ... weil es den zeilenumbruch ignoriert hat! ... aber dadurch lernt man nur dazu! 8)

mulder ...
???
Schau Dir mal DOTALL unter http://docs.python.org/lib/node46.html an!
MfG
HWK

Verfasst: Donnerstag 25. Oktober 2007, 09:56
von mulder
moin!

ich bins wieder! ... :roll:

also .. aus dem findall hab ich eine verschachtelte liste erhalten!

soweit so gut! ...

aber ich suche jetzt einen/mehrere eintrage ... ich hab zwar schon eine loesung aber soo richtig gefaellt mir das ergebnis nicht! ich wuerde es gerne kuerzer mit regular expressions loesen! aber geht das

also schaut mal bitte drueber ... und gebt mir vieleicht nen tip! ...


Code: Alles auswählen

print OUTPUT
[('MapResRefToEJB', 'Mapping Resource References to Resources'), ('Module', ' DNINUS'), ('EJB', ' '),  ....

for WERT in OUTPUT:
    if WERT[0] == 'Module'
         print OUTPUT.index(WERT)


ich denke die schleife kann man komplett mit regulare expressions ersetzten .. aber das poblem ist

Code: Alles auswählen

print OUTPUT.index(r'..(Module).*')
WASX7015E: Exception running command: "print OUTPUT.index(r'..(Web Module).*')"; exception information:
 com.ibm.bsf.BSFException: exception from Jython: Traceback (innermost last):
  File "<input>", line 1, in ?
ValueError: item not found in list
ich krieg halt nicht den "richtigen" re zusammen ..

bei dem beispiel ist

r'..(Module).*'

.. = irgendwelche zwei zeichen
(Module) = das wort "Module"
.* = weitere zeichen ... die egal sind

?????? wahrscheinlich stelle ich mich wieder zu doof an! :oops:

Verfasst: Donnerstag 25. Oktober 2007, 10:21
von BlackJack
Das Ergebnis ist genau genommen keine verschachtelte Liste sondern eine Liste mit Tupeln.

``OUTPUT.index(r'..(Module).*')`` sucht nach der Zeichenkette '..(Module).*' in einer Liste mit Tupeln. Das kann nichts finden. Und was Du da angibst ist auch kein regulärer Ausdruck, das 'r' steht für "roh" d.h. der '\' hat in so einem Zeichenkettenliteral keine besondere Bedeutung. Das findet man häufig in Verbindung mit regulären Ausdrücken, weil dort der '\' eine Bedeutung hat und man sonst jeden literalen '\' als '\\' schreiben müsste.

Du könntest Dein `OUTPUT` ganz einfach in ein Dictionary stecken und dann so darauf zugreifen:

Code: Alles auswählen

output = dict(output)
print output['Module']
Auf jeden Fall habe ich den Eindruck Du solltest mal ein oder zwei Python-Tutorials durcharbeiten.

Verfasst: Donnerstag 25. Oktober 2007, 10:29
von keppla

Code: Alles auswählen

print OUTPUT
[('MapResRefToEJB', 'Mapping Resource References to Resources'), ('Module', ' DNINUS'), ('EJB', ' '),  ....

for WERT in OUTPUT:
    if WERT[0] == 'Module'
         print OUTPUT.index(WERT)
ich denke die schleife kann man komplett mit regulare expressions ersetzten .. aber das poblem ist
komplett glaube ich eher nicht.

du übergibst zZ der methode "index" einen regulären Ausdruck als string. Index versteht aber keine Regulären ausdrücke, es versucht nur stumpf, das erste vorkommen des übergebenen Objektes zu finden, und das objekt ist nicht in der liste (da sind nur tupel drin).

Code: Alles auswählen

for name, value in OUTPUT:
  if re.match('^..Module', name):
    print value
würde afaik dein Problem lösen. Ist im prinzip deine erste Schleife, nur mit der Regex ergänzt.

P.S: um dem "es geht auch more pythonic" mal vorzubeugen:

Code: Alles auswählen

[value for name, value in output if re.match('^..Module', name)]
ginge natürlich auch.

P.S2: @blackjack: das dictionary ist mir auch durch den kopf gegangen, aber für mich sieht das so aus, als ob er alle Werte, die der Regex ..Modul.* entsprechen sucht, und nicht nur den für "Modul"

Verfasst: Donnerstag 25. Oktober 2007, 11:27
von mulder
1. @blackjack: ich arbeite gerade die tutorials durch ... und das an praxis beispielen! .. ( darum hab ich ja auch den titel mit "anfaenger" bezeichnet! ...

2. das dict geht nicht weil in dem output mehrere "module" und mehrer URIs einer application drinstehn und ich mich durch den output mit indizes durchhangeln muss! .. d.h. ich suche (im endefekt) den "moduleblock" wo als naechste zeile der wert URI steht! ... und wenn ich das in ein dict eingebe krieg ich ja alle URIs!

@keppla ... danke ...ich teste den re mal aus! ...

Verfasst: Donnerstag 25. Oktober 2007, 11:54
von keppla
mulder hat geschrieben: 2. das dict geht nicht weil in dem output mehrere "module" und mehrer URIs einer application drinstehn
könntest du dafür mal ein Beispiel posten, irgendwie werd ich nicht so schlau aus deiner Beschreibung
und ich mich durch den output mit indizes durchhangeln muss! .. d.h. ich suche (im endefekt) den "moduleblock" wo als naechste zeile der wert URI steht!
was meinst du mit moduleblock, bzw dem wert uri?

Bei gegebener Datei

Code: Alles auswählen

module: Test
irgendwas: anderes
module: Eins
URI: http://www.eins.de
suchst du da dann Eins, weil es das Modul ist, wo "als nächste zeile der Wert URI steht"?
Beschreibe mal deine Probleme etwas exakter, ich wette, ich bin nicht der Einzige, der nix versteht.
... und wenn ich das in ein dict eingebe krieg ich ja alle URIs!
äh, nope, eher nicht. Das dict gibt dir genau EINEN wert zurück, nämlich den, der mit dem gegebenen KEY assoziiert ist.
@keppla ... danke ...ich teste den re mal aus! ...
Die re war nicht der Teil, der an meinem Post interessant war. Wenn du nur die änderst, wird dir das nichts helfen.

Verfasst: Donnerstag 25. Oktober 2007, 12:03
von mulder
@keppla .... doch danke! ... hat mir geholfen! .. denn notwendigen denkanstoss gegeben! ..

:wink:

und als kurze erklaerung .. der output ist ungefaehr soo aufgebaut! ..

Code: Alles auswählen

Module:   modulname1
ejb:  ejbname
URI: appserver.war;WEB-INF/Web.xml
Server: appservername
Module:   modulname1
ejb:  ejbname2
URI: appserver2.war;WEB-INF/Web.xml
Server: appservername2
...
und das fuer verschiedene module

und daher muss ich mus ja mittels gefundenen index des modules durchhangeln ... weil die eigenschaften der module auch unterschiedlich viel sind! .. aber ich habs jetzt ... vieleich etwas umstaendlicher .. aber vieleicht poste ich zum schluss den code und ihr koennt ihn "zerreisen" :wink:

Verfasst: Donnerstag 25. Oktober 2007, 12:06
von keppla
mulder hat geschrieben:@keppla .... doch danke! ... hat mir geholfen! .. denn notwendigen denkanstoss gegeben! .
cool, das freut mich.
aber vieleicht poste ich zum schluss den code und ihr koennt ihn "zerreisen" :wink:
Ja, gerne :) Auch wenn das immer etwas besserwisserisch rüberkommt, sieh's als "konstruktive kritik".
Oder zumindest als Widerlegung der Behauptung, es gäbe immer "One And Only One Best Way" ;)

Verfasst: Donnerstag 25. Oktober 2007, 12:09
von mulder
na klar! und da ich mich in python (oder in meinem fall jython) noch nicht soo auskenne ... bin ich fuer jedweilige hilfe ... ( ob besserwisserisch gemeint oder nicht) dankbar ... :D

und ... es gibt einen " One And Only One Best Way" .. das ist immer der selbstenwickelte! weil den kann man am besten nachvollziehen! .. 8)

Verfasst: Donnerstag 25. Oktober 2007, 13:15
von BlackJack
So ganz ist mir das immer noch nicht klar und ich habe den Eindruck Du verwechselst output mit input!?

Wenn zu einem Modulnamen mehrere von den anderen Attributen gehören können, dann würde sich ein Dictionary anbieten das den Modulnamen auf eine Liste von Attribut-Dictionaries abbildet.

Verfasst: Freitag 26. Oktober 2007, 07:19
von mulder
hmm .... mal weit ausgeholt

der output ist eine websphere application server ausgabe ueber eine application!

darin sind bloecke die die verschiedenen optionen der deployten application beschreiben. daher kommt auch ein "modulname" doppelt dreifach oder x-fach vor .. weil es eigentlich nur eine menschlich leserliche ausgabe ist!... wenn ich also aus dem output .. welcher eine liste mit tupel ein dictonary mache ... koennte ich nicht auf den eigentlichen zweiten "wert" (zeite zeile) des dritten mal "modulname" vorkommen zugriefen! ..

oder geht das? ... :?:

ich dachte ( und habe es auch bisher nur so benutzt) ein dict inhalt kann man nur ueber den schluesselnamen aufrufen?!

Verfasst: Freitag 26. Oktober 2007, 08:54
von BlackJack
Bei einem Dictionary kannst Du über den Modulnamen auf einen Wert zugreifen. Der "eine" Wert kann ja aber auch eine Liste sein.

Code: Alles auswählen

def parse_modules(lines):
    result = {}
    module_name = None
    module = None
    for line in lines:
        key, value = line.split(':', 1)
        value = value.strip()
        if key == 'Module':
            if module_name is not None:
                result.setdefault(module_name, []).append(module)
            module_name = value
            module = {}
        else:
            module[key] = value
    if module_name is not None:
        result.setdefault(module_name, []).append(module)
    return result


def main():
    in_file = open('test.txt')
    modules = parse_modules(in_file.readlines())
    in_file.close()
    
    print modules
    for module_name, entries in modules.items():
        print module_name
        for entry in entries:
            print '    ' + '-' * 40
            for key, value in entry.items():
                print '    %s: %s' % (key, value)