É comum recorrer a .find() ou .index() para verificar se um texto existe em uma string — e acabar esbarrando em comportamentos estranhos, como um ValueError ou um match perdido no início da string. Sensibilidade a maiúsculas/minúsculas, limites de fatias deslocados por um e o fato de não existir um método .contains() em str aumentam a confusão. A solução é direta: use a ferramenta certa para cada caso. Use o operador in para checagens de existência, .find()/.index() para posições, .count() para contagens e .replace() para substituições — além de algumas técnicas seguras para Unicode quando a insensibilidade a caixa importa.
Como o Python lida com a busca de substrings
As strings de texto do Python são Unicode. As operações com substrings são sensíveis a maiúsculas/minúsculas por padrão e são implementadas em C para desempenho. A forma mais direta de testar se um texto aparece dentro de uma string é o operador in, que retorna um Booleano usando a implementação __contains__() da string. Quando você precisa de posições ou contagens, use os métodos dedicados de str. Os parâmetros opcionais start e end seguem a semântica de slicing: início inclusivo; fim exclusivo.
Verificação de contenção com in
Use "needle" in haystack quando você só precisa saber se a substring existe. É legível e evita lidar com índices.
text ="Banana bread"print("ban"in text)# False (case-sensitive)print("Ban"in text)# TrueTecnologia
Para verificações sem distinção de maiúsculas/minúsculas, normalize ambos os lados. .casefold() é mais consciente de Unicode do que .lower() e é meu padrão para matching sem caixa.
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 houseTecnologia
Substituição sem diferenciar maiúsculas/minúsculas
Para substituições sem distinguir maiúsculas/minúsculas preservando os padrões de caixa, use re.sub() com re.IGNORECASE, ou normalize com .casefold() se você não precisar preservar a capitalização original.
Correspondência sem diferenciar maiúsculas/minúsculas com .casefold()
.casefold() oferece uma normalização agressiva e compatível com Unicode e é preferível a .lower() para checagens sem distinção de caixa.
query ="straße"# German 'straße'
text ="STRASSE und mehr"# Uppercase variantprint(query.casefold()in text.casefold())# TrueTecnologia
Ferramentas relacionadas para prefixos e sufixos
Para inícios/fins conhecidos, use métodos dedicados — eles são mais rápidos e claros do que slicing ou regex:
s.startswith(prefix) e s.endswith(suffix) (aceitam tuplas para múltiplas opções)
s.removeprefix(prefix) e s.removesuffix(suffix) (Python 3.9+)
O fim é exclusivo, então as posições de busca espelham a semântica de slicing.
headline ="Where's Waldo?"print(headline.find("Waldo",0,6))# -1 (buscando em "Where'")print(headline.find("Waldo",0,13))# 8 (buscando até o 'o' em Waldo)Tecnologia
Exemplo de prática: busca e substituição de strings em Python
Este exemplo processa uma lista de sinopses de filmes. Ele demonstra checagens de existência, buscas com limites e substituições seguras sem 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)Tecnologia
Saída:
Window check: actor not found
Fans argue the actor scene was intentionally repetitive.
Window check: actor not foundTecnologia
Conclusão
Use o operador in para contenção simples, .find() ou .index() quando precisar de posições, .count() para contagens não sobrepostas e .replace() para substituições. Normalize com .casefold() para checagens sem distinção de caixa e prefira os helpers dedicados de prefixo/sufixo quando fizer sentido. Evite converter resultados de .find() para Booleano e trate o comportamento com substring vazia como um caso especial para manter o código com strings correto e claro.
Neste tutorial, você aprenderá tudo sobre as cadeias de caracteres do Python: fatiamento e encadeamento, manipulação e formatação com a classe Formatter, cadeias de caracteres f, modelos e muito mais!
Saiba mais sobre a técnica de formatação f-string no Python 3.6. Neste tutorial, você verá as vantagens que ele oferece e verá alguns exemplos de casos de uso.
Um tutorial introdutório completo sobre loops em Python. Aprenda e pratique loops while e for, loops aninhados, as palavras-chave break e continue, a função range e muito mais!
Mergulhe na ciência de dados com Python para analisar e visualizar seus dados de forma eficaz. Não precisa ter experiência ou conhecimento em programação.
É comum recorrer a
.find()ou.index()para verificar se um texto existe em uma string — e acabar esbarrando em comportamentos estranhos, como umValueErrorou um match perdido no início da string. Sensibilidade a maiúsculas/minúsculas, limites de fatias deslocados por um e o fato de não existir um método.contains()emstraumentam a confusão. A solução é direta: use a ferramenta certa para cada caso. Use o operadorinpara checagens de existência,.find()/.index()para posições,.count()para contagens e.replace()para substituições — além de algumas técnicas seguras para Unicode quando a insensibilidade a caixa importa.Como o Python lida com a busca de substrings
As strings de texto do Python são Unicode. As operações com substrings são sensíveis a maiúsculas/minúsculas por padrão e são implementadas em C para desempenho. A forma mais direta de testar se um texto aparece dentro de uma string é o operador
in, que retorna um Booleano usando a implementação__contains__()da string. Quando você precisa de posições ou contagens, use os métodos dedicados destr. Os parâmetros opcionaisstarteendseguem a semântica de slicing: início inclusivo; fim exclusivo.Verificação de contenção com in
Use
"needle" in haystackquando você só precisa saber se a substring existe. É legível e evita lidar com índices.Para verificações sem distinção de maiúsculas/minúsculas, normalize ambos os lados.
.casefold()é mais consciente de Unicode do que.lower()e é meu padrão para matching sem caixa."" in sé sempreTrue(a string vazia está em toda string).método str.find()
Sintaxe
str.find()retorna o menor índice da substring, ou-1se não encontrar. Os parâmetros opcionaisstarteendrestringem a busca.Exemplos e casos de uso
Use
.find()quando você precisa da posição e pode lidar com um valor “não encontrado” sem exceções.Não escreva
if s.find(sub):para checar existência. Se o match estiver no índice 0, a condição é falsy.método str.index()
Sintaxe
.index()espelha.find(), mas lançaValueErrorquando a substring não existe.Exemplos e quando escolher
Use
.index()quando a substring precisa existir e lançar uma exceção é o modo de falha adequado.método str.count()
Sintaxe
.count()retorna o número de ocorrências não sobrepostas. Também aceita limitesstarteend.Exemplos e casos de borda
Use
.count()para contagens rápidas sem regex.Caso especial: a string vazia.
método str.replace()
.replace()retorna uma nova string em que ocorrências deoldsão substituídas pornew. Usecountpara limitar substituições.Substituição de substrings
O método não é in-place; ele retorna uma cópia.
Substituição sem diferenciar maiúsculas/minúsculas
Para substituições sem distinguir maiúsculas/minúsculas preservando os padrões de caixa, use
re.sub()comre.IGNORECASE, ou normalize com.casefold()se você não precisar preservar a capitalização original.Correspondência sem diferenciar maiúsculas/minúsculas com .casefold()
.casefold()oferece uma normalização agressiva e compatível com Unicode e é preferível a.lower()para checagens sem distinção de caixa.Ferramentas relacionadas para prefixos e sufixos
Para inícios/fins conhecidos, use métodos dedicados — eles são mais rápidos e claros do que slicing ou regex:
s.startswith(prefix)es.endswith(suffix)(aceitam tuplas para múltiplas opções)s.removeprefix(prefix)es.removesuffix(suffix)(Python 3.9+)Trabalhando com colunas no pandas
Ao buscar em muitas strings em uma coluna de DataFrame, use os métodos vetorizados de string. Defina
regex=Falsepara corresponder texto literal.Observações:
regex=True, então caracteres especiais como.correspondem a qualquer caractere, a menos que você desative o regex.na=.... ComStringDtype, valores ausentes viramFalsena máscara por padrão.Armadilhas comuns e casos de borda
Não existe .contains() em str: use
"sub" in s."abc".contains("a")lançaAttributeError.Verdade/falsidade de .find(): índice
0é falsy; compare com!= -1ou prefirainpara existência..index() lança exceção: trate
ValueErrorse a substring puder estar ausente.String vazia:
"" in séTrue;s.find("")retorna0;s.count("")élen(s)+1.Sensibilidade a maiúsculas/minúsculas: todas as operações são sensíveis a caixa, a menos que você normalize ou use flags de regex.
Bytes vs. texto: não misture
bytesestrem buscas; decodifique ou codifique para igualar os tipos.Semântica de substring:
"ab" in "cat,bat"éFalsemesmo que"a"e"b"apareçam separadamente — matches precisam ser contíguos.Exemplos práticos para você testar
Estes snippets curtos mostram padrões corretos e destacam pegadinhas comuns.
Checagens de existência
Busca limitada com start e end
O fim é exclusivo, então as posições de busca espelham a semântica de slicing.
Contar e substituir
Exemplo de prática: busca e substituição de strings em Python
Este exemplo processa uma lista de sinopses de filmes. Ele demonstra checagens de existência, buscas com limites e substituições seguras sem regex.
Saída:
Conclusão
Use o operador
inpara contenção simples,.find()ou.index()quando precisar de posições,.count()para contagens não sobrepostas e.replace()para substituições. Normalize com.casefold()para checagens sem distinção de caixa e prefira os helpers dedicados de prefixo/sufixo quando fizer sentido. Evite converter resultados de.find()para Booleano e trate o comportamento com substring vazia como um caso especial para manter o código com strings correto e claro.