Struktur Auswerten...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 27. April 2005, 13:45

Habe eine Struktur Auszuwerten:

Code: Alles auswählen

class Mission
{
   [...]
   addOns[]=
   {
      "lsr_rang",
      [...]
      "ofpec_blood"
   };
   [...]
   addOnsAuto[]=
   {
      "lsr_rang",
      [...]
      "BMP2"
   };
   [...]
}; 
Mir geht es um die Einträge bei addOns und addOnsAuto. Ich könnte mir vorstellen, das es mit RE recht einfach ist daran zu kommen. Gibt es dennoch auch andere, evtl. sinnvollere Möglichkeiten?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 27. April 2005, 15:55

Hoi Jens,

was genau meinst Du mit "Struktur auswerten"? Alles zwischen den geschweiften Klammern hinter dem Gleichheitszeichen auslesen? Wie?
Insgesamt klingt das schon nach einem Problem für regular expressions, aber u.U. geht das auch mit einem Linewalk a la: for line in ....
Aber Du solltest vielleicht das Problem erst einmal etwas spezifizieren.

Gruß,
Christian
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 27. April 2005, 16:06

Sorry... Mir geht es um die Listeneinträge die definiert werden.

Im obrigen Beispiel entsprechent möchte ich das folgende raus haben:

Code: Alles auswählen

addOns = [ "lsr_rang", ... , "ofpec_blood" ]
addOnsAuto = [ "lsr_rang", ... , "BMP2" ]
Eigentlich ist die verwendete Syntax in der die Listeneinträge abgelegt werden sehr klar... Deswegen frage ich mich ob es eine elegantere Lösung außer RE gibt. (Wobei RE wahrscheinlich die schnellere zu realisierende ist)
Gibt es evtl. in Python selber schon einen Parser den man auf diese Syntax "konfigurieren" kann?
Verkompliziere ich die Dinge evtl.?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 27. April 2005, 16:17

Grundsätzlich gilt ja: Keine Parser selber schreiben, weil es gibt sie schon. Die Recherche darfst Du allerdings selber machen :twisted:
Ansonsten: Unbedingt REs nehmen. Zwei matched groups und Du bist von allem ab. Das verlangt zwar etwas mehr Hirnschmals spart Dir aber einige Zeilen Code und Du weißt in drei Monaten auch noch genau was Du gemacht hast.

Gruß,
Christian
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 27. April 2005, 16:19

OK, danke... Ich denke ich werde dann doch mit RE experimentieren....

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 27. April 2005, 16:34

Nachtrag:
Schau doch mal hier: http://www.python.org/moin/LanguageParsing
Und wenn Du da nichts findest, stelle Deine Frage doch einfach mal in der Mailingliste der SIG.

Warum selber schreiben, was es schon gibt?

Gruß,
Christian
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 27. April 2005, 16:37

jens hat geschrieben:OK, danke... Ich denke ich werde dann doch mit RE experimentieren....
Fertig! :P

Code: Alles auswählen

import re

data = """class Mission
{
   [...]
   addOns[]=
   {
      "lsr_rang",
      "ofpec_blood"
   };
   [...]
   addOnsAuto[]=
   {
      "lsr_rang",
      "BMP2"
   };
   [...]
};"""

gefunden = re.findall(
   "addOns[].*?{(.*?)}|addOnsAuto[].*?{(.*?)}", 
   data.replace("\n", ""), 
   re.I | re.M
)

addOns = []
for item in gefunden[0].split(","):
   addOns.append(item.replace('"', '').strip())
addOnsAuto = []
for item in gefunden[1].split(","):
   addOnsAuto.append(item.replace('"', '').strip())

print addOns
print addOnsAuto
lg
Gerold
:-)
Zuletzt geändert von gerold am Donnerstag 28. April 2005, 08:10, insgesamt 2-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mittwoch 27. April 2005, 16:39

Chapeau! (hab ich aber nicht getestet)
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Mittwoch 27. April 2005, 16:45

Hi!

Eine Version ohne Regex. So kompliziert wie nur möglich, scheint aber zu funktionieren :wink: (das Ergebnis wird in ein Dictionary gespeichert):

Code: Alles auswählen

f = file("text.txt","r")
dic = {}
ads = []
for line in f:
    if '{' in line: continue
    elif '};' in line:
        if chunk:
            dic[chunk] = ads
        chunk = ""
        ads = []
    elif '[]=' in line:
        chunk = line.strip().strip('[]=')
        ads = []
    else:
        ad = line.strip().strip('".').strip('[]')
        ads.append(ad)
print dic
Gruß, mawe
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 27. April 2005, 16:46

CM hat geschrieben:Schau doch mal hier: http://www.python.org/moin/LanguageParsing
Ne, danke... Ich hab mir das die hälte angeschaut, aber nix wirklich verstanden :oops: Ich denke RE ist in diesem Fall die einfachste Variante...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 27. April 2005, 17:05

mawe hat geschrieben: Eine Version ohne Regex. So kompliziert wie nur möglich, scheint aber zu funktionieren
Hi mawe!

Und ich dachte mal, Regular Expressions sind kompliziert :wink: :D :lol:

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 27. April 2005, 17:20

gerold hat geschrieben:Fertig! :P
Wow, ich hab noch garnicht angefangen...
In deiner Variante ist allerdings auch ein fehler :lol:
Sie spuckt nämlich zweimal das selbe raus:
['lsr_rang', 'ofpec_blood']
['lsr_rang', 'ofpec_blood']
Meine Variante geht in zwei Schritten vor:

Code: Alles auswählen

import re

data = """class Mission
{
   [...]
   addOns[]=
   {
      "lsr_rang",
      "ofpec_blood"
   };
   [...]
   addOnsAuto[]=
   {
      "lsr_rang",
      "BMP2"
   };
   [...]
};"""

def get( typ, data ):
    # Erst alles in den {}-Klammern rausfischen
    result = re.findall(
        typ+'\[\]=.*?{(.*?)}',
        data,
        re.S
    )
    # Alle Werte in "" zurück geben
    return re.findall( r'"(.*?)"', result[0] )

print get( "addOns", data )
print get( "addOnsAuto", data )
Ausgabe:
['lsr_rang', 'ofpec_blood']
['lsr_rang', 'BMP2']

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 27. April 2005, 17:35

jens hat geschrieben: In deiner Variante ist allerdings auch ein fehler :lol:
Sie spuckt nämlich zweimal das selbe raus:
['lsr_rang', 'ofpec_blood']
['lsr_rang', 'ofpec_blood']
Sorry, ist jetzt ausgebessert. Das war mal wieder so ein Copy&Paste-Fehler.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Mittwoch 27. April 2005, 22:37

gerold hat geschrieben:

Code: Alles auswählen

gefunden = re.findall(
   "addOns[].*?{(.*?)}|addOnsAuto[].*?{(.*?)}", 
   data.replace("\n", ""), 
   re.I or re.M
)
Die letzte Zeile tut nicht das was sie soll:

Code: Alles auswählen

In [8]: re.I or re.M
Out[8]: 2

In [9]: re.I | re.M
Out[9]: 10
Der ``or``-Operator gibt eines der beiden Objekte zurück (im vorliegenden Fall das `re.I`), während ``|`` eine Oder-Verknüpfung der Bits von zwei Zahlen ist.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 28. April 2005, 08:08

BlackJack hat geschrieben: Die letzte Zeile tut nicht das was sie soll:

Code: Alles auswählen

In [8]: re.I or re.M
Out[8]: 2

In [9]: re.I | re.M
Out[9]: 10
Der ``or``-Operator gibt eines der beiden Objekte zurück (im vorliegenden Fall das `re.I`), während ``|`` eine Oder-Verknüpfung der Bits von zwei Zahlen ist.
Hi BlackJack!

Danke! :P

Das erklärt, das mir unerklärliche Verhalten, einiger meiner RE-Funktionen. Das ist auch der Grund gewesen, weshalb ich oft vorher mit "replace" die Zeilenumbrüche entferne, obwohl diese mit re.M kein Problem mehr sein dürften. Da liest man vor dem Schlafen die Python-Doku und hat am nächsten Tag nur mehr "Oder" im Kopf :wink:

Das war wieder mal ein super Hinweis.

lg
Gerold
:-)

PS: Ich ändere meinen Beispielcode, damit nicht noch jemand den gleichen Fehler macht.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten