Seite 1 von 2
String durchsuchen
Verfasst: Dienstag 11. September 2012, 17:14
von OttoPython
Hallo Leute,
ich habe folgendes vor:
ich möchte ein String nach einem bestimmten Wort durchsuchen lassen.
Hinter dem Wort kommen aber noch je nach Quelle unterschiedliche viele Ziffern und zum Schluss eine Klammer ")" und danach kommen wieder buchstaben.
Alle Zeichenfolgen Vor, innerhalb des Gesuchten, und Nach dem Gesuchten varieren in der Anzahl der Zeichen.
Ich habe eine Möglichkeit mir zurecht geschustert wie es funktioniert
ABER
gibt es noch eine einfachere und kürzere oder intelligentere Art und Weise als meine Überlegung?
BSP: [getestet]
Code: Alles auswählen
>>> a = 'pw try oks Key 1.0.0 (120) tst kw'
>>> b = a.find('Key')
>>> c = a.find(')') + 1
>>> d = a[b:c]
>>> print d
Key 1.0.0 (120)
oder
BSP2: [getestet]
Code: Alles auswählen
>>> a = 'pw try oks Key 1.0.0 (120) tst kw'
>>> b = a[a.find('Key'):a.find(')')+1]
>>> print b
Key 1.0.0 (120)
sieht beides iwie nicht sehr professionell aus

Re: String durchsuchen
Verfasst: Dienstag 11. September 2012, 17:37
von cofi
Nun, wenn du es kuerzer haben willst, gibt es immernoch regulaere Ausdruecke:
Code: Alles auswählen
In [1]: a = 'pw try oks Key 1.0.0 (120) tst kw'
In [2]: import re
In [3]: re.findall(r'(Key.*?\))', a)
Out[3]: ['Key 1.0.0 (120)']
Re: String durchsuchen
Verfasst: Donnerstag 13. September 2012, 08:52
von OttoPython
cool.. danke
kannst du mir aber den Ausdruck (Key.*?\)) erklären?
und mit welcher ausgabe kann ich besser weiter arbeiten (meine oder deine)? ich benötige dieses gefundene zum späteren vergleich. das ganze stellt nämlich Versionsnummern eines Programms da.. welche in Datendateien geschrieben sind und ich muss die versionsnummern auf gleichheit prüfen bevor ich mein hauptskrippt starten und an den dateien arbeiten kann.
Re: String durchsuchen
Verfasst: Donnerstag 13. September 2012, 09:22
von BlackJack
@OttoPython: Die äusseren Klammern erzeugen eine Gruppe — damit kann man bei `findall()` beeinflussen was im Ergebnis auftaucht, obwohl das in diesem Fall nicht nötig ist. Man könnte die erste Klammer zum Beispiel hinter 'Key' verschieben, wenn man diesen festen Bestandteil nicht im Ergebnis haben möchte:
Code: Alles auswählen
In [56]: re.findall(r'Key (.*?\))', a)
Out[56]: ['1.0.0 (120)']
'Key' erkennt genau die Zeichenfolge 'Key'. Gefolgt von beliebigen Zeichen ('.'), beliebig oft (inklusive gar nicht) ('*'), aber so wenig wie möglich („non-greedy”) ('?'), gefolgt von einer schliessenden Klammer ('\)'). Ohne das '?' würde versucht so viele wie möglich Zeichen vor einer schliessenden Klammer zu erkennen. Das macht dann einen Unterschied, wenn mehrere davon in der Zeichenkette vorkommen.
Neben der Dokumentation zum `re`-Modul gibt es in der Python-Dokumentation auch noch ein Howto zu regulären Ausdrücken:
http://docs.python.org/howto/regex.html
Re: String durchsuchen
Verfasst: Dienstag 18. September 2012, 15:07
von OttoPython
hi BlackJack
danke dafür!
habe nun aber ein kleines Problem.. ich muss nun doch nach 2 Bestimmten Strings suchen, um es zu vereinfachen
nehmen wir das obige Beispiel:
Code: Alles auswählen
import re
a = 'pw try oks Key 1.0.0 (120) tst kw'
re.findall(r'(Key.*?\))', a)
nun muss ich aber nicht nur nach 'Key' sondern auch nach 'ikey' suchen... das Problem an der Sache ist, dass das k bei dem ikey wirklich klein geschrieben wird. Nehme ich die funktion re.findall findet python nun aber nichts.. case sensitivity.. kann ich das irgendwie ändern, dass Python nicht case sensitive ist? also das ich nach nem großen 'K' als auch kleinen 'k' suchen lassen kann?!
beste Grüße
Re: String durchsuchen
Verfasst: Dienstag 18. September 2012, 15:10
von webspider
Entweder du veränderst den regulären Ausdruck oder nutzt das Flag re.IGNORECASE beim Durchsuchen.
Es steckt alles in der Doku drin.
Re: String durchsuchen
Verfasst: Dienstag 18. September 2012, 15:27
von cofi
Code: Alles auswählen
In [1]: import re
In [2]: a = 'pw try oks Key 1.0.0 (120) tst kw, ikey foo bar (123)'
In [3]: re.findall(r'(?:Key|ikey).*?\)', a)
Out[3]: ['Key 1.0.0 (120)', 'ikey foo bar (123)']
Konzept: Non-capturing groups.
Wenn du RE benutzt, solltest du dich aber wirklich zumindest mit der Dokumentation von `re` beschaeftigen (die Dokumentation hat noch ein weitergehendes Tutorial), besser noch mit der Theorie dahinter beschaeftigen.
Re: String durchsuchen
Verfasst: Mittwoch 19. September 2012, 07:55
von OttoPython
dankeschön!
funktioniert!
ja werde ich mir mal anschauen.. ist wirklich hilfreich.. mit re habe ich vorher noch gar nicht gearbeitet. wird wohl zeit mir das mal zu gemüte zu führen.
Re: String durchsuchen
Verfasst: Mittwoch 19. September 2012, 11:25
von OttoPython
gibt es die Möglichkeit zum Beispiel wenn meine Liste so aussieht:
nach dem ';' zu suchen aber bis zu der stelle davor auszugeben? mit meinem allerersten versuch über das .find war das ja möglich aber in der doku zu re habe ich dazu nichts gefunden.
anderer Gedanke meinerseits war
da die Unterscheidung zwischen Key und ikey eh getroffen wird und die Liste mit Key ein '()' enthält und die Liste von ikey nur ';' also keine Klammern enthält nach beiden Suchen zu lassen und dann was er findet bis dahin die ausgabe macht.
meine Überlegung dazu hatte ich in der doku zum re.search gesehen bei dem eine Unterscheidung durch [);] mögliche wäre
aber baue ich das in den befehl ein:
Code: Alles auswählen
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\re.py", line 177, in f
return _compile(pattern, flags).findall(st
File "C:\Python27\lib\re.py", line 244, in _
raise error, v # invalid expression
sre_constants.error: unbalanced parenthesis
was tun? beide Ansätze bekomme ich nicht gelöst
Re: String durchsuchen
Verfasst: Mittwoch 19. September 2012, 12:03
von BlackJack
@OttoPython: Du kommst da mit den Klammern durcheinander. Klammern die zum regulären Ausdruck gehören, also nicht durch einen '\' davon befreit sind, müssen in korrekt verschachtelt in Paaren auftreten. Denn sie kapseln ja einen Teilausdruck. Du hast da zwei schliessende Klammern für die es kein Gegenstück gibt, wo der geklammerte Teilausdruck anfangen würde.
Das bei 'ikey' keine Klammern sondern ein ';' den gesuchten Teil abschliesst, ist jetzt eine neue Bedingung oder? Gibt es das Semikolon auch immer bei 'Key'? Also könnte man die Klammern komplett ignorieren und immer bis zu einem ';' suchen?
Bei solchen Sachen ist es in der Regel besser sich zuerst klar zu machen wie *alle* Variationen aussehen können, die man suchen möchte, und *dafür* einen regulären Ausdruck zu entwickeln, als immer mit neuen Bedingung und Randfällen anzukommen und einen Ausdruck zu erweitern. Ist natürlich nicht immer möglich, vor allem wenn man neue Bedingungen selber erst beim Auswerten der Daten findet.
Wenn Du etwas nicht mit Ergebnis von `findall()` haben möchtest, dann muss es halt einfach ausserhalb der („capturing”) Gruppe stehen.
Re: String durchsuchen
Verfasst: Mittwoch 19. September 2012, 13:26
von cofi
Nehm dir BlackJacks Post zu Herzen und besonders unterstuetze ich, dass du RE nicht stueckweise zusammenbaust, sondern erst das ganze Bild betrachtest.
Der richtige Ausdruck sollte dieser sein:
Klammern sind Teil der RE Metasprache (wie z.B. + und ?), willst du wirklich eine Klammer matchen muss es \) heissen. Du hast das genau verdreht.
Re: String durchsuchen
Verfasst: Mittwoch 19. September 2012, 13:31
von OttoPython
Hey danke,
also es ist wirklich der Fall das bei beiden 'Key' und 'ikey' ein Simikolon folgt und nur der eine Fall ohne eine Klammer davor endet. Ich habe ja bereits bis zum Simikolon für mich suchen lassen nur mich hat halt das Simikolon gestört dass es in der ausgabe mitz drin is..habe jetzt die Lösung =)
der andere Gedanke kam mir nur in den Sinn ob es überhaupt möglich ist nach 2 unterschiedlichen Sachen bis zu 2 unterschiedlichen Enden suchen zu lassen..
edit:
des rätsel gesammter Lösung wäre dann:
re.findall(r'((?:Key|ikey).+?)(?:\)|;)', a)
das sind wirklich ein haufen informationen in diesen klammern und da muss man auch erstmal genau den überblick haben, was ist jetzt wirklich vom reg. Ausdruck und was will ich dadrin machen.
Danke dafür =)
Re: String durchsuchen
Verfasst: Mittwoch 19. September 2012, 14:34
von cofi
Na wenn beide Faelle mit `;` enden geht das viel einfacher: r"((?:Key|ikey).+?);"
Da du ; zu einem \; gemacht hast: Rate nicht, sondern schau in die Dokumentation. Hier sind besondere Zeichen aufgelistet:
http://docs.python.org/library/re.html
Re: String durchsuchen
Verfasst: Samstag 6. März 2021, 01:40
von spicer
Hallo Gemeinde
Ich hole diesen alten Thread mal aus der Versenkung ^^
Aber das passt genau da rein (hoffe ich. Sonst einfach verschieben bitte).
Das Vorherige handelt wahrscheinlich von Python2. Hier aber ist Python3 an der Reihe.
loc.sun(date.today()).items()
gibt folgendes aus:
dict_items([('sunset', datetime.datetime(2021, 3, 5, 18, 22, 39, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>)), ('dawn', datetime.datetime(2021, 3, 5, 6, 30, 14, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>)), ('noon', datetime.datetime(2021, 3, 5, 12, 41, 39, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>)), ('dusk', datetime.datetime(2021, 3, 5, 18, 53, 3, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>)), ('sunrise', datetime.datetime(2021, 3, 5, 7, 0, 38, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>))])
Das nächste mal:
dict_items([('noon', datetime.datetime(2021, 3, 5, 12, 41, 39, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>)), ('dawn', datetime.datetime(2021, 3, 5, 6, 30, 14, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>)), ('sunrise', datetime.datetime(2021, 3, 5, 7, 0, 38, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>)), ('sunset', datetime.datetime(2021, 3, 5, 18, 22, 39, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>)), ('dusk', datetime.datetime(2021, 3, 5, 18, 53, 3, tzinfo=<DstTzInfo 'Europe/Zurich' CET+1:00:00 STD>))])
Die Reihenfolge von sunrise und sunset ist immer anders.
Darum gibt mir:
sun1 = str(list(data)[1])
zeit = sun1.split(', ')
print(zeit[4] + ":" + zeit[5])
immer eine andere, falsche Zeit aus.
Wie bewerkstellige ich es, dass vor dem lesen der Zeit (Zahl 4 und 5) zuerst auf den vorangehenden Text sunrise bzw sunset geachtet wird?
Vorher mit Python2 funktionierte das ohne den list Befehl. Mit Python3 leider nicht mehr und man braucht den list Befehl, welcher aber nicht mehr gleich reagiert.
Früher sah die Zeile so aus:
sun1 = str(data[1])
Habe nun mit
import re
d = re.findall(r"sunset', datetime.datetime\((.*?tzinfo)", str(zeit))
versucht. Aber das bringt mich auch nicht zur Lösung.
Ich hoffe, ich konnte das Problem einigermassen verständlich beschreiben. Ist gar nicht so einfach ^^
Danke schonmal im Voraus und ich freue mich, ein Teil dieser Community zu sein. Die Avatar Restriktionen sind zu bissig. Darum hab ich noch keinen passenden gefunden.
Re: String durchsuchen
Verfasst: Samstag 6. März 2021, 09:08
von sparrow
Das ist doch eine Datenstruktur und keine Zeichenkette. Warum wandelst du die denn in eine Zeiuchenkette und versucht dann Zeichenkettenoperationen drauf?
Es handelt sich um ein dictionary. Und darin befindet sich eine Zeichenkette ("sunset", "noon", ...) als Schlüssel und datetime.datetime-Objekt als Wert.
Schau dir mal an, was dicts sind und wie sie funktionieren.
Re: String durchsuchen
Verfasst: Samstag 6. März 2021, 09:27
von spicer
Habe doch recherchiert. Komme aber nicht weiter.
Darum meine Frage. Ich bin kein Python Profi!
Könntest Du mir bitte ein Beispiel nach Deinem Wissen geben?
Re: String durchsuchen
Verfasst: Samstag 6. März 2021, 09:30
von spicer
Habe doch recherchiert. Komme aber nicht weiter.
Darum meine Frage. Ich bin kein Python Profi!
Könntest Du mir bitte ein Beispiel nach Deinem Wissen geben?
Zur Foren SW. Ist voll schräg. wenn ich einen doppelpost lösche sind beide weg.
Wenn ich wieder poste, ist es wieder doppelt da!
Re: String durchsuchen
Verfasst: Samstag 6. März 2021, 10:02
von __blackjack__
@spicer: In der Python-Dokumentation gibt es ein Tutorial, das solltest Du durcharbeiten. Da werden die Grundlagen vermittelt.
Re: String durchsuchen
Verfasst: Samstag 6. März 2021, 10:48
von kbr
@spicer: Wie sparrow schon schrieb, handelt es sich bei "data" um ein Dictionary. Ein Dictionary ist ein grundlegender Datentyp in Python:
Code: Alles auswählen
>>> i_am_the_dictionary["i_am_the_key"] = "i_am_the_value"
>>> print(i_am_the_dictionary["i_am_the_key"])
i_am_the_value
Jetzt brauchst Du nur noch "data" und z.B. "sunset" passend einsetzen.
Re: String durchsuchen
Verfasst: Samstag 6. März 2021, 12:38
von spicer
Hmm, ich schnall das nicht
Habe zu C64 Zeiten Basic und Assembler gecodet.
Später REXX gelernt...aber das geht mir iwie nicht rein

Sorry
PS:
Was ich auch nicht begreife; den unterschied von Python2 zu Python3 mit dem LIST Befehl.
Das war doch auch in P2 logisch. Warum soll das in P3 nicht mehr logisch sein?