Es ist verlockend, zu .find() oder .index() zu greifen, um zu prüfen, ob Text in einem String vorkommt — und dann über Kuriositäten wie einen ValueError oder einen verpassten Treffer am Stringanfang zu stolpern. Groß-/Kleinschreibung, Off-by-one-Slice-Grenzen und die Tatsache, dass es keine .contains()-Methode auf str gibt, verstärken die Verwirrung. Die Lösung ist simpel: das passende Werkzeug wählen. Für Existenzprüfungen nutzen wir den Operator in, für Positionen .find()/.index(), für Zählungen .count() und für Ersetzungen .replace() — ergänzt um ein paar Unicode-sichere Techniken, wenn Groß-/Kleinschreibung egal ist.
Wie Python die Suche nach Teilstrings handhabt
Pythons Text-Strings sind Unicode. Teilstring-Operationen sind standardmäßig case-sensitiv und in C implementiert, um schnell zu sein. Der direkteste Weg zu testen, ob Text in einem String vorkommt, ist der Operator in, der ein Boolean zurückgibt und die __contains__()-Implementierung des Strings nutzt. Wenn du Positionen oder Zählwerte brauchst, nimm die entsprechenden str-Methoden. Optionale Parameter start und end folgen der Slice-Semantik: Start ist inklusiv, Ende exklusiv.
Enthaltensein mit in
Verwende "needle" in haystack, wenn dich nur interessiert, ob der Teilstring existiert. Das ist gut lesbar und erspart dir Index-Handling.
text ="Banana bread"print("ban"in text)# False (case-sensitive)print("Ban"in text)# TrueBereitgestellt von
Für case-insensitive Checks normalisierst du beide Seiten. .casefold() ist Unicode-bewusster als .lower() und meine Standardwahl für vergleiche ohne Beachtung der Groß-/Kleinschreibung.
pattern ="ban"print(pattern.casefold()in text.casefold())# TrueBereitgestellt von
Wann verwenden: schnelle Existenzchecks, Eingabevalidierung, Listen filtern.
Sonderfall: "" in s ist immer True (der leere String steckt in jedem String).
Methode str.find()
Syntax
str.find() gibt den kleinsten Index des Teilstrings zurück oder -1, wenn nichts gefunden wird. Optionale start- und end-Werte schränken die Suche ein.
Die Methode arbeitet nicht in-place; sie liefert eine Kopie zurück.
message ="The red house is between the blue house and the old house"print(message.replace("house","car"))# The red car is between the blue car and the old carprint(message.replace("house","car",2))# The red car is between the blue car and the old houseBereitgestellt von
Case-insensitive Ersetzungen
Für Ersetzungen ohne Beachtung der Groß-/Kleinschreibung und mit Erhalt des ursprünglichen Kasus nutze re.sub() mit re.IGNORECASE, oder normalisiere mit .casefold(), wenn dir der ursprüngliche Kasus egal ist.
Case-insensitive Abgleiche mit .casefold()
.casefold() bietet eine aggressive, Unicode-bewusste Normalisierung der Groß-/Kleinschreibung und ist .lower() für vergleiche ohne Kasusunterscheidung vorzuziehen.
query ="straße"# German 'straße'
text ="STRASSE und mehr"# Uppercase variantprint(query.casefold()in text.casefold())# TrueBereitgestellt von
Verwandte Tools für Präfixe und Suffixe
Für bekannte Starts/Enden sind dedizierte Methoden die beste Wahl — schneller und klarer als Slices oder Regex:
s.startswith(prefix) und s.endswith(suffix) (akzeptieren Tupel für mehrere Optionen)
s.removeprefix(prefix) und s.removesuffix(suffix) (Python 3.9+)
filename ="draft_report_v2.pdf"print(filename.removeprefix("draft_"))# report_v2.pdfprint(filename.endswith((".pdf",".docx")))# TrueBereitgestellt von
Arbeiten mit Pandas-Spalten
Wenn du viele Strings in einer DataFrame-Spalte durchsuchst, nutze vektorisierte String-Methoden. Setze regex=False, um wörtlichen Text zu matchen.
import pandas as pd
cities = pd.Series(["New York","Yorktown",None,"Toronto"], dtype="string")
mask = cities.str.contains("York", regex=False, na=False)print(mask.tolist())# [True, True, False, False]Bereitgestellt von
Hinweise:
Standardmäßig ist regex=True, daher matchen Sonderzeichen wie . jedes Zeichen, sofern du Regex nicht deaktivierst.
Null-Werte über na=... steuern. Mit StringDtype sind fehlende Werte im Masken-Resultat standardmäßig False.
Häufige Fallstricke und Sonderfälle
Kein .contains() auf str: Nutze "sub" in s. "abc".contains("a") wirft AttributeError.
Wahrheitswert von .find(): Index 0 ist falsey; vergleiche mit != -1 oder nutze für Existenz in.
.index() wirft: Behandle ValueError, wenn der Teilstring fehlen könnte.
Leerer Teilstring:"" in s ist True; s.find("") ergibt 0; s.count("") ist len(s)+1.
Groß-/Kleinschreibung: Alle Operationen sind case-sensitiv, sofern du nicht normalisierst oder Regex-Flags nutzt.
Bytes vs. Text: Mische bytes und str nicht in Suchen; dekodiere oder kodiere, sodass die Typen passen.
Teilstring-Semantik:"ab" in "cat,bat" ist False, obwohl "a" und "b" einzeln vorkommen — Treffer müssen zusammenhängend sein.
Hands-on-Beispiele zum Ausprobieren
Diese kurzen Snippets zeigen bewährte Muster und heben typische Stolpersteine hervor.
Existenzprüfungen
headline ="Where's Waldo?"print("Waldo"in headline)# Trueprint("Wenda"in headline)# Falseprint(headline.find("Waldo"))# 8print(headline.find("Wenda"))# -1Bereitgestellt von
Begrenzte Suche mit start und end
Das Ende ist exklusiv, die Suchpositionen folgen also der Slice-Semantik.
headline ="Where's Waldo?"print(headline.find("Waldo",0,6))# -1 (Suche in "Where'")print(headline.find("Waldo",0,13))# 8 (Suche bis zum 'o' in Waldo)Bereitgestellt von
Praxisbeispiel: Strings in Python suchen und ersetzen
Dieses Beispiel verarbeitet eine Liste mit Film-Blurbs. Es zeigt Existenzprüfungen, begrenzte Suchen und sichere Ersetzungen ohne Regex.
blurbs =["Critics say the lead actor delivers a career-best performance.","Fans argue the actor actor scene was intentionally repetitive.","A clever cameo steals the show."]for blurb in blurbs:# Check whether "actor" appears between indexes 20 and 40 (end exclusive).
window_has_actor ="actor".casefold()in blurb[20:40].casefold()ifnot window_has_actor:print("Window check: actor not found")continue# If "actor actor" appears, collapse to a single "actor".if"actor actor"in blurb:print(blurb.replace("actor actor","actor"))# If "actor actor actor" appears, collapse to a single "actor".elif"actor actor actor"in blurb:print(blurb.replace("actor actor actor","actor"))else:print(blurb)Bereitgestellt von
Ausgabe:
Window check: actor not found
Fans argue the actor scene was intentionally repetitive.
Window check: actor not foundBereitgestellt von
Fazit
Nutze den Operator in für schlichtes Enthaltensein, .find() oder .index(), wenn du Positionen brauchst, .count() für nicht-überlappende Zählungen und .replace() für Ersetzungen. Normalisiere mit .casefold() für case-insensitive Checks und greife bei Bedarf zu dedizierten Präfix-/Suffix-Helfern. Wir vermeiden es, .find()-Ergebnisse zu Booleans zu konvertieren, und behandeln das Verhalten mit leerem Teilstring als Sonderfall — so bleibt String-Code korrekt und gut lesbar.
Lerne die Funktionen und Methoden von Python-Listen kennen. Schau dir jetzt die Code-Beispiele für list() und andere Python-Funktionen und -Methoden an!
Erforsche Pythons match-case: eine Anleitung zu seiner Syntax, Anwendungen in Data Science und ML sowie eine vergleichende Analyse mit dem traditionellen switch-case.
Es ist verlockend, zu
.find()oder.index()zu greifen, um zu prüfen, ob Text in einem String vorkommt — und dann über Kuriositäten wie einenValueErroroder einen verpassten Treffer am Stringanfang zu stolpern. Groß-/Kleinschreibung, Off-by-one-Slice-Grenzen und die Tatsache, dass es keine.contains()-Methode aufstrgibt, verstärken die Verwirrung. Die Lösung ist simpel: das passende Werkzeug wählen. Für Existenzprüfungen nutzen wir den Operatorin, für Positionen.find()/.index(), für Zählungen.count()und für Ersetzungen.replace()— ergänzt um ein paar Unicode-sichere Techniken, wenn Groß-/Kleinschreibung egal ist.Wie Python die Suche nach Teilstrings handhabt
Pythons Text-Strings sind Unicode. Teilstring-Operationen sind standardmäßig case-sensitiv und in C implementiert, um schnell zu sein. Der direkteste Weg zu testen, ob Text in einem String vorkommt, ist der Operator
in, der ein Boolean zurückgibt und die__contains__()-Implementierung des Strings nutzt. Wenn du Positionen oder Zählwerte brauchst, nimm die entsprechendenstr-Methoden. Optionale Parameterstartundendfolgen der Slice-Semantik: Start ist inklusiv, Ende exklusiv.Enthaltensein mit in
Verwende
"needle" in haystack, wenn dich nur interessiert, ob der Teilstring existiert. Das ist gut lesbar und erspart dir Index-Handling.Für case-insensitive Checks normalisierst du beide Seiten.
.casefold()ist Unicode-bewusster als.lower()und meine Standardwahl für vergleiche ohne Beachtung der Groß-/Kleinschreibung."" in sist immerTrue(der leere String steckt in jedem String).Methode str.find()
Syntax
str.find()gibt den kleinsten Index des Teilstrings zurück oder-1, wenn nichts gefunden wird. Optionalestart- undend-Werte schränken die Suche ein.Beispiele und Anwendungsfälle
Nutze
.find(), wenn du die Position brauchst und einen „nicht gefunden“-Wert ohne Exceptions verarbeiten kannst.Schreibe nicht
if s.find(sub):für Existenzprüfungen. Steht der Treffer an Index 0, ist die Bedingung falsey.Methode str.index()
Syntax
.index()spiegelt.find(), wirft aber einenValueError, wenn der Teilstring fehlt.Beispiele und wann du es wählst
Nutze
.index(), wenn der Teilstring existieren muss und eine Exception das gewünschte Fehlersignal ist.Methode str.count()
Syntax
.count()gibt die Anzahl nicht-überlappender Vorkommen zurück.startundendwerden ebenfalls unterstützt.Beispiele und Sonderfälle
Nutze
.count()für schnelle Zählungen ohne Regex.Spezialfall: der leere String.
Methode str.replace()
.replace()gibt einen neuen String zurück, in dem Vorkommen vonolddurchnewersetzt werden. Mitcountbegrenzt du die Anzahl der Ersetzungen.Teilstrings ersetzen
Die Methode arbeitet nicht in-place; sie liefert eine Kopie zurück.
Case-insensitive Ersetzungen
Für Ersetzungen ohne Beachtung der Groß-/Kleinschreibung und mit Erhalt des ursprünglichen Kasus nutze
re.sub()mitre.IGNORECASE, oder normalisiere mit.casefold(), wenn dir der ursprüngliche Kasus egal ist.Case-insensitive Abgleiche mit .casefold()
.casefold()bietet eine aggressive, Unicode-bewusste Normalisierung der Groß-/Kleinschreibung und ist.lower()für vergleiche ohne Kasusunterscheidung vorzuziehen.Verwandte Tools für Präfixe und Suffixe
Für bekannte Starts/Enden sind dedizierte Methoden die beste Wahl — schneller und klarer als Slices oder Regex:
s.startswith(prefix)unds.endswith(suffix)(akzeptieren Tupel für mehrere Optionen)s.removeprefix(prefix)unds.removesuffix(suffix)(Python 3.9+)Arbeiten mit Pandas-Spalten
Wenn du viele Strings in einer DataFrame-Spalte durchsuchst, nutze vektorisierte String-Methoden. Setze
regex=False, um wörtlichen Text zu matchen.Hinweise:
regex=True, daher matchen Sonderzeichen wie.jedes Zeichen, sofern du Regex nicht deaktivierst.na=...steuern. MitStringDtypesind fehlende Werte im Masken-Resultat standardmäßigFalse.Häufige Fallstricke und Sonderfälle
Kein .contains() auf str: Nutze
"sub" in s."abc".contains("a")wirftAttributeError.Wahrheitswert von .find(): Index
0ist falsey; vergleiche mit!= -1oder nutze für Existenzin..index() wirft: Behandle
ValueError, wenn der Teilstring fehlen könnte.Leerer Teilstring:
"" in sistTrue;s.find("")ergibt0;s.count("")istlen(s)+1.Groß-/Kleinschreibung: Alle Operationen sind case-sensitiv, sofern du nicht normalisierst oder Regex-Flags nutzt.
Bytes vs. Text: Mische
bytesundstrnicht in Suchen; dekodiere oder kodiere, sodass die Typen passen.Teilstring-Semantik:
"ab" in "cat,bat"istFalse, obwohl"a"und"b"einzeln vorkommen — Treffer müssen zusammenhängend sein.Hands-on-Beispiele zum Ausprobieren
Diese kurzen Snippets zeigen bewährte Muster und heben typische Stolpersteine hervor.
Existenzprüfungen
Begrenzte Suche mit start und end
Das Ende ist exklusiv, die Suchpositionen folgen also der Slice-Semantik.
Zählen und Ersetzen
Praxisbeispiel: Strings in Python suchen und ersetzen
Dieses Beispiel verarbeitet eine Liste mit Film-Blurbs. Es zeigt Existenzprüfungen, begrenzte Suchen und sichere Ersetzungen ohne Regex.
Ausgabe:
Fazit
Nutze den Operator
infür schlichtes Enthaltensein,.find()oder.index(), wenn du Positionen brauchst,.count()für nicht-überlappende Zählungen und.replace()für Ersetzungen. Normalisiere mit.casefold()für case-insensitive Checks und greife bei Bedarf zu dedizierten Präfix-/Suffix-Helfern. Wir vermeiden es,.find()-Ergebnisse zu Booleans zu konvertieren, und behandeln das Verhalten mit leerem Teilstring als Sonderfall — so bleibt String-Code korrekt und gut lesbar.