Suchmuster

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.
kawkaw
User
Beiträge: 11
Registriert: Montag 13. April 2009, 09:52

Hallo,

ich habe ein Problem mit meinem Porgramm. Ich will, dass mein gesuchter Muster zeilenweise zurueckgegeben wird, d.h nach jedem muster, soll eine neue Zeile beginnen.

Mein Text sieht so aus

('Dorf', ', Ein dorf ist blablabla'), ('Stadt', ', Ein Stadt ist blablabla'), (........

Ich will dieser Text so ausgegeben

('Dorf', ', Ein dorf ist blablabla')

('Stadt', ', Ein Stadt ist blablabla')

file= open("muster.txt","r")
for line in file.readlines():
p = re.compile(r'\[\[(.*?)\]\](.*?)[(\\\n\*\+)]')
#p = re.split("\'\)\," , line)
result = p.findall(line)

f = open("musterzurueck.txt" , "w").write(str(result))

Ich habe vieles probiert. Split etc..
kann mir jemand weiter helfen
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wo kommen die Textdateien her? Kannst Du das Format beeinflussen - wenn ja, dann nutze doch ein Standardformat wie JSON o.ä.

Zudem benutze bitte Code-Tags; so kann man Deinen Quellcode schwer lesen, da u.a. die Einrückungen verloren gehen.

Ich sehe das Problem nicht:

Code: Alles auswählen

In [1]: text = "('Dorf', ', Ein dorf ist blablabla'), ('Stadt', ', Ein Stadt ist
 blablabla')"

In [3]: import re

In [7]: re.findall("\(.*?\)", text)
Out[7]:
["('Dorf', ', Ein dorf ist blablabla')",
 "('Stadt', ', Ein Stadt ist blablabla')"]

In [10]: for fragment in re.findall("\(.*?\)", text):
   ....:     print fragment
   ....:
   ....:
('Dorf', ', Ein dorf ist blablabla')
('Stadt', ', Ein Stadt ist blablabla')
Einfach den Ausdruck zwischen den Klammern durch das "?" auf non-greedy stellen, dann bekommst Du die Klammern einzeln als Liste. Diese dann normal iterieren und fertig.

Ach ja: readlines() ist unnötig; man kann über Files direkt iterieren. Allerdings: Wozu hier überhaupt so vorgehen? Nimm einfach den gesamten Dateinhalt und suche darüber.

das re.compile() ist schön und gut - verfehlt aber den Zweck, wenn man es in einer Schleife ständig neu vronimmt ;-)
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

wenn des Augangstext _wirklich_ ein String mit Tupeln innendrin ist, geht das auch viel einfacher:

Code: Alles auswählen

>>> text = "('Dorf', ', Ein dorf ist blablabla'), ('Stadt', ', Ein Stadt ist blablabla')"
>>> text2 = eval(text)
>>> text2
(('Dorf', ', Ein dorf ist blablabla'), ('Stadt', ', Ein Stadt ist blablabla'))
Dann hast du eine Tupel von Tupeln, über das man sehr schön iterieren kann.

Gruß, noisefloor
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

noisefloor hat geschrieben:Hallo,

wenn des Augangstext _wirklich_ ein String mit Tupeln innendrin ist, geht das auch viel einfacher:

Code: Alles auswählen

>>> text = "('Dorf', ', Ein dorf ist blablabla'), ('Stadt', ', Ein Stadt ist blablabla')"
>>> text2 = eval(text)
>>> text2
(('Dorf', ', Ein dorf ist blablabla'), ('Stadt', ', Ein Stadt ist blablabla'))
Dann hast du eine Tupel von Tupeln, über das man sehr schön iterieren kann.

Gruß, noisefloor
Auf die Gefahren von eval() wolltest Du nicht eingehen? Imho sollte man das immer tun, wenn man so etwas in den Raum wirft; speziell da der OP augenscheinlich wenig Python-Erfahrung mitbringt.

Wie ich im ersten Satz schon schrieb: Das Format als solches sollte dringend ausgetauscht werden, wenn möglich!
kawkaw
User
Beiträge: 11
Registriert: Montag 13. April 2009, 09:52

Code: Alles auswählen

#! /usr/bin/env python
import MySQLdb
import re
db=MySQLdb.connect(host='localhost', db='datenbank', user='root',
passwd='password')
c=db.cursor()
c.execute('SELECT blabla )


querytext=c.fetchall()
f = open( "wikitextexp.txt","w" )
for querytext in c:
    f.write(str(querytext))


#ich bekommen da einen Text aus dem DB mit viele unnötige Tags, Table.....


f.close()

file= open("muster.txt","r")
for line in file.readlines():
	p = re.compile(r'\[\[(.*?)\]\](.*?)[(\\\n\*\+)]')
	#p = re.split("\'\)\," , line)
	result = p.findall(line)
	
#ich bekomme so etwas aber in eine Zeile "('Dorf', ', Ein dorf ist blablabla'), ('Stadt', ', Ein Stadt ist blablabla')"

	
f = open("musterzurueck.txt" , "w").write(str(result))



file.close()



Vielleicht ist es möglich oben den text zu beeinflussen.
Dank Hyperion, ich habe deinen Vorschlag probiert, bekomme aber als Antwort Iterator needed oder sowas. Dank noisefloor für den Vorschlag.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Könntest Du...

... bitte den Code syntaktisch korrekt hier reinstellen?

... beschreiben, was Du genau machst / erreichen willst? (Ich habe keine Lust, mir reverse engineering mäßig anzugucken, was Die DB mit der Textdatei zu tun hat)

So kommen wir hier nicht weiter!
BlackJack

@kawkaw: Du solltest halt einfach keine Zeichenkettenrepräsentationen von Python-Objekten in Dateien schreiben, sondern ein vernünftiges Dateiformat verwenden, welches man später auch wieder einfach einlesen kann.

Wenn's Python-only ist, wäre das `pickle`-Modul naheliegend, ansonsten schau Dir mal das `json`- oder das `csv`-Modul an.
kawkaw
User
Beiträge: 11
Registriert: Montag 13. April 2009, 09:52

Vielen Dank,
ja ich werde es mit JSON versuchen. Ich versuche ein Offilne Reader zu wikipedia zu programmieren. Ich arbeite daran seit paar Tage.
Ich dachte mit Regex könnte mal irgendwie ein pattern zwischen zwei Klammer holen und diese als Liste zurueckgeben. Ich denke wenn ich noch weiter daran arbeite werde ich es schaffen. Ich sagte nur mal im Forum versuchen, da es erfahrene User gibt die weiterhelfen können. Dank
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hyperion hat geschrieben: Auf die Gefahren von eval() wolltest Du nicht eingehen? Imho sollte man das immer tun, wenn man so etwas in den Raum wirft; speziell da der OP augenscheinlich wenig Python-Erfahrung mitbringt.
Hatte ich erst überlegt, dann aber verworfen. Weil: die Datenquelle war unbekannt, daher wäre alles spekulativ gewesen. Außerdem habe ich fest damit gerechnet, dass jemand sowas in den Raum wirft. ;-)

Da die Datenquelle am langen Ende eine DB ist, die man nicht selber mit Daten befühlt hat, sollte man eval in dieser Form sicherlich _nicht_ ohne weiteres nutzen. :-)

Zum Thema: Das

Code: Alles auswählen

str(querytext)
macht IMHO nie Sinn. Die Python DB-API liefert immer ein Tuple (oder eine Liste) zurück, daher macht es immer Sinn, mit den darin enthaltenen Elementen "etwas zu machen", bevor man diese in eine Datei schreibt.

Je nach Umfang der Daten macht neben pickle auch anydbm oder eine csv-Datei Sinn.

Gruß, noisefloor
kawkaw
User
Beiträge: 11
Registriert: Montag 13. April 2009, 09:52

macht IMHO nie Sinn. Die Python DB-API liefert immer ein Tuple (oder eine Liste) zurück, daher macht es immer Sinn, mit den darin enthaltenen Elementen "etwas zu machen", bevor man diese in eine Datei schreibt.
Ich habe versucht einfach mit .line.replace( "\(\)" , "") die ( zu ersezten aber ich bekommen als Fehlermeldung.
"STR" has no attribute Findall?

Das wäre eine Möglichkeit ansatt den Text zw den Klammern (.*?) zu extrahieren, die Klammer zu durch nichts zu ersetzen.

Warum habe ich diese Fehlermeldung?
BlackJack

@kawkaw: Das ist sicher keine Fehlermeldung von Python, denn da steht sicher nicht "STR" oder "Findall". Und bei welchem Quelltext kommt das?

Wozu brauchst Du das denn? Ich denke Du wolltest jetzt JSON verwenden!?
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

kawkaw hat geschrieben:Ich habe versucht einfach mit .line.replace( "\(\)" , "") die ( zu ersezten aber ich bekommen als Fehlermeldung.
"STR" has no attribute Findall?
Die Fehlermeldung besagt, dass du hier Methoden von Strings und des Moduls re durcheinanderwirfst.
Eine pythonische Lösung käme ohne re aus und sähe in etwa so aus:

Code: Alles auswählen

In [2]: text =('Dorf', ', Ein dorf ist blablabla'), ('Stadt', ', Ein Stadt ist blablabla'),

In [3]: type(text)
Out[3]: <type 'tuple'>

In [4]: for line in text:
   ...:     print line
   ...:
('Dorf', ', Ein dorf ist blablabla')
('Stadt', ', Ein Stadt ist blablabla')
(Ist hier in ipython, daher die In [3]: etc.)

Durch wildes Ausprobieren kommst du nicht weiter, arbeite lieber das Tutorial durch.
EDIT: Code war vermurkst.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich verstehe das Konzept auch immer noch nicht. Du willst wikipedia-Artikel lokal abspeichern und dazu suchst Du ein Datenformat, oder wie?

Wenn ja, böte sich doch ggf auch noch SQLite an - da ist die Transformation ggf. nicht so groß. Ansonsten wurde JSON ja schon genannt.
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@kawkaw: Nochmal - der elementare Fehler ist, dass du das komplette Ergebnis der DB-Abfrage einfach so in einen String umwandelst!

Gruß, noisefloor
kawkaw
User
Beiträge: 11
Registriert: Montag 13. April 2009, 09:52

Dank noisefloor,
ich glaube ich bin auf den richtigen Weg. Ich habe csv.writer benutzt und die Datei ist ganz normal gespeichert. Ich will nur noch mit Regex den Text parsen. Ich habe vieles gemacht mit perl aber dieses Programm will ich mit Python schreiben und ich hoffe es wird klappen.

Mein Text sieht so aus.
[[Dorf]], ein dorf ist blabla.......
[[Stadt]], ein Stadt ist blabla....


früher war alles in einem Satz gespeichert horizontal gespeichert. Ich hoffe nun die Arbeit wird leichter.

Ich denke csv.Dictwriter wird helfen mit RegEx Dorf als key und den Rest als Values zu haben
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich verstehe immer noch nicht, was genau erreicht werden soll. Der OP geht ja leider auch nicht auf Nachfragen oder Hinweise ein. Diese Attitüde mag ich persönlich nicht - demotiviert sie einen doch ziemlich zu helfen.

Naja, dann noch viel Erfolg beim Prokeln!
kawkaw
User
Beiträge: 11
Registriert: Montag 13. April 2009, 09:52

OK
ich erkläre kurz was ich machen will.

Erstens in meinem gespeicherten DB die Tabelle Text lesen und diese als Text speichern ( Das ist jetzt ok) und dann in diesem Text mit Hilfe von Regex muster extrahieren und um zu erreichen, dass die daten so aussehen:

Word1: Begriffserklärungerklärung
Word2: Begriffserklärungerklärung

etc.....

Ist es überhaupt möglich in einem CSV datei mit Regex zu suchen. Ich hoffe das ist klar.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Das "Aussehen" ist ziemlich unbedeutend - die Datenstruktur dahinter ist der casus knacktus! Was Du da zeigst erinnert sofort an ein Dictionary in Python. Du musst also ein solches aus den Daten der Datenbank erzeugen.

Nun ist die Frage, wie die Tabelle aufgebaut ist - ohne diese Info kann man nicht weiter machen. Kennt man deren Struktur, so kann man auch ableiten, wie man diese Tupel in ein Dict bekommt.

Als letztes stellt sich weiterhin die Frage, was letztendlich mit der Datenstruktur weiter gemacht werden soll. Denn gff. böte es sich an, selbige in einer anderen DB zu lassen, wie etwa SQLite oder einen KV-Store zu nutzen, anstatt das ganze zu pickeln oder per JSON abzulegen. Aber darüber kann man erst etwas sagen, wenn da mehr Infos zu kommen. (Und ich denke es lohnt sich darüber zu diskutieren!)
kawkaw
User
Beiträge: 11
Registriert: Montag 13. April 2009, 09:52

Die Tabelle ist die Wikipedia dump. Ich will den Text haben und ihn mit Regex verfeinern.

Jetzt habe ich so etwas

Code: Alles auswählen

result = c.fetchall()
f = csv.writer(open( "text1.txt","w" ))
for line in result:
	f.writerow(line)

file= open("text1.txt","rb")
for line in file.readlines():
	p = re.compile(r'\[\[(.*?)\]\](.*?)[(\\\n\*\+)]')
	#p = line.replace("\(\)" , " ")
	result = p.findall(line)

	
	
f = csv.writer(open("text2.txt" , "w").writerow(str(result)))

	
Fehlermeldung
Traceback (most recent call last):
File "page_query_test.py", line 28, in <module>
f = csv.writer(open("wikiparsedexp.txt" , "w").writerow(str(result)))
AttributeError: 'file' object has no attribute 'writerow'
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Zum letzten Mal die Frage:
Warum der Zwischenschritt über die Datei, ist das wirklich nötig??

Außerdem ist die Klammer in der letzten Zeile von deinem Code falsch gesetzt, vor dem writerow muss noch eine schließende Klammer. Das ist der Fehler.

Und verwende nächstes mal Python-Code-Tags, dann ist der Quelltext gleich noch schön formatiert (ohne die Leerzeichen): [ code=py ][ /code ]

Edit:
Noch ein paar Dinge:
- öffne Dateien mit `with`
- verwende keine builtin-Namen wie `file`
- `for line in file` macht das gleiche wie `for line in file.readlines()` und ist speicherschonender
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
Antworten