È normale ricorrere a .find() o .index() per verificare se un testo esiste in una stringa, per poi imbattersi in comportamenti strani come un ValueError o una corrispondenza mancata all’inizio della stringa. La distinzione tra maiuscole e minuscole, i limiti di slice sfasati di uno e il fatto che non esista un metodo .contains() su str aumentano la confusione. La soluzione è semplice: usa lo strumento giusto per il compito. Per i controlli di esistenza ci affidiamo all’operatore in, a .find()/.index() per le posizioni, a .count() per i conteggi e a .replace() per le sostituzioni, oltre a qualche tecnica sicura per Unicode quando serve l’insensibilità alle maiuscole/minuscole.
Come Python gestisce la ricerca di sottostringhe
Le stringhe di testo in Python sono Unicode. Le operazioni sulle sottostringhe distinguono tra maiuscole e minuscole per impostazione predefinita e sono implementate in C per velocità. Il modo più diretto per verificare se un testo compare all’interno di una stringa è l’operatore in, che restituisce un booleano usando l’implementazione __contains__() della stringa. Quando ti servono posizioni o conteggi, usa i metodi dedicati di str. I parametri opzionali start ed end seguono la semantica degli slice: start è inclusivo; end è esclusivo.
Contenimento con in
Usa "needle" in haystack quando ti interessa solo se la sottostringa esiste. È leggibile e ti evita di gestire indici.
text ="Banana bread"print("ban"in text)# False (case-sensitive)print("Ban"in text)# TrueOfferto da
Per controlli case-insensitive, normalizza entrambi i lati. .casefold() è più attento a Unicode di .lower() ed è la mia scelta predefinita per i confronti senza distinzione tra maiuscole e minuscole.
pattern ="ban"print(pattern.casefold()in text.casefold())# TrueOfferto da
Quando usarlo: controlli rapidi di esistenza, validazione dell’input, filtraggio di liste.
Caso limite: "" in s è sempre True (la stringa vuota è in ogni stringa).
Metodo str.find()
Sintassi
str.find() restituisce l’indice più basso della sottostringa, oppure -1 se non è trovata. I parametri opzionali start ed end limitano la ricerca.
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 houseOfferto da
Sostituzione case-insensitive
Per sostituzioni senza distinzione tra maiuscole e minuscole preservando i pattern di maiuscole, usa re.sub() con re.IGNORECASE, oppure normalizza con .casefold() se non ti serve preservare il casing originale.
Confronti case-insensitive con .casefold()
.casefold() offre una normalizzazione aggressiva e attenta a Unicode ed è preferibile a .lower() per confronti senza distinzione tra maiuscole e minuscole.
query ="straße"# German 'straße'
text ="STRASSE und mehr"# Uppercase variantprint(query.casefold()in text.casefold())# TrueOfferto da
Strumenti correlati per prefissi e suffissi
Per inizi/fini noti, usa i metodi dedicati: sono più veloci e chiari rispetto a slicing o regex:
s.startswith(prefix) e s.endswith(suffix) (accettano tuple per più opzioni)
s.removeprefix(prefix) e s.removesuffix(suffix) (Python 3.9+)
filename ="draft_report_v2.pdf"print(filename.removeprefix("draft_"))# report_v2.pdfprint(filename.endswith((".pdf",".docx")))# TrueOfferto da
Lavorare con le colonne di Pandas
Quando cerchi in molte stringhe in una colonna di DataFrame, usa i metodi stringa vettorializzati. Imposta regex=False per cercare testo letterale.
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]Offerto da
Note:
Per impostazione predefinita, regex=True, quindi caratteri speciali come . corrispondono a qualsiasi carattere a meno che tu non disabiliti le regex.
Gestisci i null tramite na=.... Con StringDtype, i valori mancanti predefiniti sono False nella mask.
Errori comuni e casi limite
Nessun .contains() su str: usa "sub" in s. "abc".contains("a") genera AttributeError.
Veridicità di .find(): l’indice 0 è falsy; confronta con != -1 o preferisci in per l’esistenza.
.index() solleva eccezioni: gestisci ValueError se la sottostringa potrebbe essere assente.
Stringa vuota:"" in s è True; s.find("") restituisce 0; s.count("") è len(s)+1.
Distinzione tra maiuscole e minuscole: tutte le operazioni sono case-sensitive a meno che tu non normalizzi o usi flag regex.
Byte vs. testo: non mescolare bytes e str nelle ricerche; decodifica o codifica per far corrispondere i tipi.
Semantica delle sottostringhe:"ab" in "cat,bat" è False anche se "a" e "b" compaiono separatamente: le corrispondenze devono essere contigue.
Esempi pratici da eseguire
Questi brevi snippet mostrano i pattern corretti e mettono in evidenza i tranelli più comuni.
Controlli di esistenza
headline ="Where's Waldo?"print("Waldo"in headline)# Trueprint("Wenda"in headline)# Falseprint(headline.find("Waldo"))# 8print(headline.find("Wenda"))# -1Offerto da
Ricerca limitata con start ed end
End è esclusivo, quindi le posizioni di ricerca rispecchiano la semantica degli slice.
headline ="Where's Waldo?"print(headline.find("Waldo",0,6))# -1 (searching "Where'")print(headline.find("Waldo",0,13))# 8 (searching up to the 'o' in Waldo)Offerto da
Esercizio di pratica: ricerca e sostituzione di stringhe in Python
Questo esempio elabora una lista di descrizioni di film. Mostra controlli di esistenza, ricerche limitate e sostituzioni sicure senza 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)Offerto da
Output:
Window check: actor not found
Fans argue the actor scene was intentionally repetitive.
Window check: actor not foundOfferto da
Conclusione
Usa l’operatore in per il semplice contenimento, .find() o .index() quando ti servono posizioni, .count() per conteggi non sovrapposti e .replace() per le sostituzioni. Normalizza con .casefold() per controlli case-insensitive e preferisci gli helper dedicati per prefissi/suffissi quando opportuno. Evitiamo di convertire i risultati di .find() in booleani e trattiamo il comportamento con sottostringa vuota come caso speciale per mantenere il codice sulle stringhe corretto e chiaro.
Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
È normale ricorrere a
.find()o.index()per verificare se un testo esiste in una stringa, per poi imbattersi in comportamenti strani come unValueErroro una corrispondenza mancata all’inizio della stringa. La distinzione tra maiuscole e minuscole, i limiti di slice sfasati di uno e il fatto che non esista un metodo.contains()sustraumentano la confusione. La soluzione è semplice: usa lo strumento giusto per il compito. Per i controlli di esistenza ci affidiamo all’operatorein, a.find()/.index()per le posizioni, a.count()per i conteggi e a.replace()per le sostituzioni, oltre a qualche tecnica sicura per Unicode quando serve l’insensibilità alle maiuscole/minuscole.Come Python gestisce la ricerca di sottostringhe
Le stringhe di testo in Python sono Unicode. Le operazioni sulle sottostringhe distinguono tra maiuscole e minuscole per impostazione predefinita e sono implementate in C per velocità. Il modo più diretto per verificare se un testo compare all’interno di una stringa è l’operatore
in, che restituisce un booleano usando l’implementazione__contains__()della stringa. Quando ti servono posizioni o conteggi, usa i metodi dedicati distr. I parametri opzionalistartedendseguono la semantica degli slice: start è inclusivo; end è esclusivo.Contenimento con in
Usa
"needle" in haystackquando ti interessa solo se la sottostringa esiste. È leggibile e ti evita di gestire indici.Per controlli case-insensitive, normalizza entrambi i lati.
.casefold()è più attento a Unicode di.lower()ed è la mia scelta predefinita per i confronti senza distinzione tra maiuscole e minuscole."" in sè sempreTrue(la stringa vuota è in ogni stringa).Metodo str.find()
Sintassi
str.find()restituisce l’indice più basso della sottostringa, oppure-1se non è trovata. I parametri opzionalistartedendlimitano la ricerca.Esempi e casi d’uso
Usa
.find()quando ti serve la posizione e puoi gestire un valore “non trovato” senza eccezioni.Non scrivere
if s.find(sub):per controllare l’esistenza. Se la corrispondenza è all’indice 0, la condizione è falsy.Metodo str.index()
Sintassi
.index()rispecchia.find()ma generaValueErrorquando la sottostringa è assente.Esempi e quando sceglierlo
Usa
.index()quando la sottostringa deve esistere e un’eccezione è la modalità di errore corretta.Metodo str.count()
Sintassi
.count()restituisce il numero di occorrenze non sovrapposte. Accetta anche i limitistartedend.Esempi e casi limite
Usa
.count()per conteggi rapidi senza regex.Caso speciale: la stringa vuota.
Metodo str.replace()
.replace()restituisce una nuova stringa in cui le occorrenze dioldsono sostituite danew. Usacountper limitare le sostituzioni.Sostituire sottostringhe
Il metodo non è in-place; restituisce una copia.
Sostituzione case-insensitive
Per sostituzioni senza distinzione tra maiuscole e minuscole preservando i pattern di maiuscole, usa
re.sub()conre.IGNORECASE, oppure normalizza con.casefold()se non ti serve preservare il casing originale.Confronti case-insensitive con .casefold()
.casefold()offre una normalizzazione aggressiva e attenta a Unicode ed è preferibile a.lower()per confronti senza distinzione tra maiuscole e minuscole.Strumenti correlati per prefissi e suffissi
Per inizi/fini noti, usa i metodi dedicati: sono più veloci e chiari rispetto a slicing o regex:
s.startswith(prefix)es.endswith(suffix)(accettano tuple per più opzioni)s.removeprefix(prefix)es.removesuffix(suffix)(Python 3.9+)Lavorare con le colonne di Pandas
Quando cerchi in molte stringhe in una colonna di DataFrame, usa i metodi stringa vettorializzati. Imposta
regex=Falseper cercare testo letterale.Note:
regex=True, quindi caratteri speciali come.corrispondono a qualsiasi carattere a meno che tu non disabiliti le regex.na=.... ConStringDtype, i valori mancanti predefiniti sonoFalsenella mask.Errori comuni e casi limite
Nessun .contains() su str: usa
"sub" in s."abc".contains("a")generaAttributeError.Veridicità di .find(): l’indice
0è falsy; confronta con!= -1o preferisciinper l’esistenza..index() solleva eccezioni: gestisci
ValueErrorse la sottostringa potrebbe essere assente.Stringa vuota:
"" in sèTrue;s.find("")restituisce0;s.count("")èlen(s)+1.Distinzione tra maiuscole e minuscole: tutte le operazioni sono case-sensitive a meno che tu non normalizzi o usi flag regex.
Byte vs. testo: non mescolare
bytesestrnelle ricerche; decodifica o codifica per far corrispondere i tipi.Semantica delle sottostringhe:
"ab" in "cat,bat"èFalseanche se"a"e"b"compaiono separatamente: le corrispondenze devono essere contigue.Esempi pratici da eseguire
Questi brevi snippet mostrano i pattern corretti e mettono in evidenza i tranelli più comuni.
Controlli di esistenza
Ricerca limitata con start ed end
End è esclusivo, quindi le posizioni di ricerca rispecchiano la semantica degli slice.
Conteggio e sostituzione
Esercizio di pratica: ricerca e sostituzione di stringhe in Python
Questo esempio elabora una lista di descrizioni di film. Mostra controlli di esistenza, ricerche limitate e sostituzioni sicure senza regex.
Output:
Conclusione
Usa l’operatore
inper il semplice contenimento,.find()o.index()quando ti servono posizioni,.count()per conteggi non sovrapposti e.replace()per le sostituzioni. Normalizza con.casefold()per controlli case-insensitive e preferisci gli helper dedicati per prefissi/suffissi quando opportuno. Evitiamo di convertire i risultati di.find()in booleani e trattiamo il comportamento con sottostringa vuota come caso speciale per mantenere il codice sulle stringhe corretto e chiaro.