mitmario.dev

Suchen in Text

Python Sandbox 4 Min Lesezeit 6 BeispieleLektion 3 von 6

Ein Postfach mit vierhundert Mails, und irgendwo darin stecken die Rechnungen. Mit == kommst du nicht weit, denn keine Betreffzeile heißt einfach nur Rechnung. Die eine heißt Ihre Rechnung Nr. 4711, die nächste RECHNUNG für Bestellung 0815, und in einer dritten steht das Wort mitten in Abrechnung. Du suchst also keinen gleichen Text, sondern einen, in dem etwas vorkommt.

Vorkommen

Steht es drin
betreff = "Ihre Rechnung Nr. 4711"
print("Rechnung" in betreff)
print("rechnung" in betreff)
print("Mahnung" in betreff)
print("Mahnung" not in betreff)

in kennst du aus Lektion 5.2. Dort hat es gefragt, ob ein Eintrag in einer Liste steht. Bei Text fragt es, ob ein Stück davon irgendwo im Text vorkommt, an welcher Stelle auch immer. "Rechnung" in betreff ist True, weil das Wort mitten in Ihre Rechnung Nr. 4711 steht. not in fragt andersherum.

Der Unterschied zur Liste ist feiner, als er aussieht. In einer Liste vergleicht in ganze Einträge. "milch" in ["Hafermilch"] ist False, weil dort kein Eintrag milch steht. In einem Text wird nach einem Stück gesucht, und "milch" in "Hafermilch" ist True.

Wo die Grenze liegt, siehst du in der zweiten Zeile. rechnung klein geschrieben kommt in dem Betreff nicht vor. Wie bei jedem Vergleich zählt jeder einzelne Buchstabe, groß oder klein.

Groß und klein egal

Groß und klein ignorieren
betreff = "RECHNUNG für Bestellung 0815"
suchwort = "Rechnung"
print(suchwort in betreff)
print(suchwort in betreff.lower())
print("rechnung" in betreff.lower())

Groß und klein ignorieren kann in nicht. Deshalb macht man beide Seiten gleich, bevor man fragt, und zwar mit lower(). Beide Seiten ist dabei wörtlich gemeint.

Das zeigt die mittlere Zeile. betreff.lower() macht den Betreff klein, das Suchwort Rechnung hat aber noch sein großes R. In rechnung für bestellung 0815 kommt Rechnung nicht vor. In der letzten Zeile steht das Suchwort klein da. Erst dort gibt es den Treffer.

Wenn das Suchwort aus dem Programm selbst kommt, kannst du es so wie dort gleich klein hinschreiben. Kommt es von außen, etwa aus input(), weißt du nicht, wie es getippt wurde. Dann gehört das lower() an beide Seiten.

Mitten im Wort

Auch mitten im Wort
betreffzeilen = ["Abrechnung Nebenkosten",
                 "Rechnungsadresse geändert",
                 "Neue Berechnung Ihres Beitrags"]
for betreff in betreffzeilen:
    print("rechnung" in betreff.lower(), betreff)

in weiß nichts von Wörtern. Es findet rechnung in Abrechnung und in Rechnungsadresse, und meistens will man das auch. Es findet das Wort aber genauso in Berechnung, und eine Mail über die neue Berechnung eines Beitrags ist keine Rechnung. Für die meisten Fragen im Büro reicht in trotzdem völlig. Man sollte nur wissen, was es mitfindet.

Die Stelle finden

Wo steht das @
adresse = "mia.schulz@example.org"
stelle = adresse.find("@")
print(stelle)
print(adresse[:stelle])
print(adresse[stelle + 1:])
print(adresse.find("#"))

find (finden) sagt nicht nur, ob etwas vorkommt, sondern auch wo. Zurück kommt die Position, an der das gesuchte Stück anfängt, gezählt ab null wie bei Listen. Das @ in der Adresse steht auf Position 10. Mit Ausschnitten bekommst du davor den Namen und dahinter die Domain, also den Teil der Adresse, der zum Mailanbieter gehört. So zerlegt man Text an einer Stelle, die man erst suchen muss.

Kommt das Gesuchte nicht vor, gibt find -1 zurück. Nicht 0, denn 0 ist eine echte Position. Dort steht etwas ganz am Anfang.

find in einem if
for betreff in ["Rechnung März", "Ihre Rechnung", "Newsletter"]:
    if betreff.find("Rechnung"):
        print("Treffer:", betreff)

Und daraus wird eine Falle. Im Beispiel sollen alle Betreffzeilen mit Rechnung herausgesucht werden, und heraus kommen die falschen. Rechnung März fehlt, und Newsletter ist ein Treffer.

Den Grund kennst du aus Lektion 3.5. In einem if gilt 0 als falsch und jede andere Zahl als wahr, auch -1. In Rechnung März steht das Wort auf Position 0, also fällt die Zeile durch. Newsletter hat das Wort gar nicht, bekommt -1 und ist dabei.

Für die Frage „kommt es vor?“ ist deshalb in das richtige Werkzeug. find nimmst du, wenn du die Position wirklich brauchst, und dann fragst du ausdrücklich nach != -1.

Zählen

Wie oft
zettel = "Milch, Brot, milch, Eier, MILCH"
print(zettel.count("Milch"))
print(zettel.lower().count("milch"))

count (zählen) sagt, wie oft ein Stück im Text vorkommt. Auch hier zählen Groß und klein mit. Milch kommt genau einmal vor, denn milch und MILCH sind für Python etwas anderes. Erst nach lower() sind es drei. Das ist derselbe Zähler wie in den Schleifen, nur ohne Schleife.

Was die Aufgabe will

Gesucht wird im Postfach vom Anfang. Ein Suchwort und eine Reihe von Betreffzeilen kommen aus einer Datei. Das Programm soll jede Zeile ausgeben, in der das Suchwort vorkommt, egal ob groß oder klein geschrieben und auch dann, wenn es mitten im Wort steht. Darunter steht, wie viele es waren.

Zum Mitnehmen

Mit in fragst du, ob ein Stück Text irgendwo vorkommt, find nennt die Position und count die Anzahl. Alle drei achten auf Groß und klein, und wem das egal sein soll, der macht beide Seiten mit lower() klein. Ohne Treffer liefert find -1, und in einem if zählt das als wahr.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 6 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, dein Code läuft auf einem Server

    Öffnet sich mit dem Basis Konto.