Es habitual recurrir a .find() o .index() para comprobar si un texto existe en una cadena y encontrarse con comportamientos raros como un ValueError o pasar por alto una coincidencia al inicio de la cadena. La sensibilidad a mayúsculas y minúsculas, los límites de corte desfasados y el hecho de que str no tenga un método .contains() aumentan la confusión. La solución es sencilla: usa la herramienta adecuada. Para comprobar existencia, nos apoyamos en el operador in; para posiciones, en .find()/.index(); para recuentos, en .count(); y para sustituciones, en .replace(), además de algunas técnicas seguras con Unicode cuando importa la insensibilidad a mayúsculas.
Cómo gestiona Python la búsqueda de subcadenas
Las cadenas de texto en Python son Unicode. Las operaciones con subcadenas distinguen mayúsculas por defecto y están implementadas en C para ser rápidas. La forma más directa de comprobar si un texto aparece dentro de una cadena es el operador in, que devuelve un booleano usando la implementación __contains__() de la cadena. Cuando necesites posiciones o recuentos, usa los métodos específicos de str. Los parámetros opcionales start y end siguen la semántica de los cortes: el inicio es inclusivo y el final, exclusivo.
Contención con in
Usa "needle" in haystack cuando solo te importe si la subcadena existe. Es legible y evita manejar índices.
text ="Banana bread"print("ban"in text)# False (case-sensitive)print("Ban"in text)# TrueCon la tecnología de
Para comprobaciones sin distinguir mayúsculas, normaliza ambos lados. .casefold() es más consciente de Unicode que .lower() y es mi opción por defecto para comparaciones sin mayúsculas.
pattern ="ban"print(pattern.casefold()in text.casefold())# TrueCon la tecnología de
Cuándo usarlo: comprobaciones rápidas de existencia, validación de entradas, filtrado de listas.
Caso límite: "" in s siempre es True (la cadena vacía está en todas las cadenas).
Método str.find()
Sintaxis
str.find() devuelve el índice más bajo de la subcadena o -1 si no se encuentra. Los parámetros opcionales start y end acotan la búsqueda.
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 houseCon la tecnología de
Sustitución sin distinguir mayúsculas
Para sustituciones sin distinguir mayúsculas conservando los patrones de capitalización, usa re.sub() con re.IGNORECASE, o normaliza con .casefold() si no necesitas preservar el formato original.
Coincidencias sin distinguir mayúsculas con .casefold()
.casefold() ofrece una normalización agresiva y consciente de Unicode y se prefiere frente a .lower() para comprobaciones sin mayúsculas.
query ="straße"# German 'straße'
text ="STRASSE und mehr"# Uppercase variantprint(query.casefold()in text.casefold())# TrueCon la tecnología de
Herramientas relacionadas para prefijos y sufijos
Si conoces el inicio o el final, usa métodos específicos: son más rápidos y claros que cortar o usar regex:
s.startswith(prefix) y s.endswith(suffix) (aceptan tuplas para múltiples opciones)
s.removeprefix(prefix) y s.removesuffix(suffix) (Python 3.9+)
filename ="draft_report_v2.pdf"print(filename.removeprefix("draft_"))# report_v2.pdfprint(filename.endswith((".pdf",".docx")))# TrueCon la tecnología de
Trabajar con columnas de pandas
Al buscar en muchas cadenas de una columna de DataFrame, usa los métodos vectorizados de cadenas. Establece regex=False para hacer coincidencias literales.
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]Con la tecnología de
Notas:
Por defecto, regex=True, así que caracteres especiales como . coinciden con cualquier carácter si no desactivas regex.
Gestiona nulos con na=.... Con StringDtype, los valores ausentes se convierten por defecto en False en la máscara.
Errores comunes y casos límite
No existe .contains() en str: usa "sub" in s. "abc".contains("a") lanza AttributeError.
Veracidad de .find(): el índice 0 es falsy; compara con != -1 o mejor usa in para existencia.
.index() lanza excepciones: gestiona ValueError si la subcadena podría no estar.
Cadena vacía:"" in s es True; s.find("") devuelve 0; s.count("") es len(s)+1.
Sensibilidad a mayúsculas: todas las operaciones distinguen mayúsculas salvo que normalices o uses flags de regex.
Bytes vs. texto: no mezcles bytes y str en búsquedas; decodifica o codifica para igualar tipos.
Semántica de subcadenas:"ab" in "cat,bat" es False aunque "a" y "b" aparezcan por separado: las coincidencias deben ser contiguas.
Ejemplos prácticos para ejecutar
Estos fragmentos cortos muestran patrones correctos y señalan tropiezos habituales.
Comprobaciones de existencia
headline ="Where's Waldo?"print("Waldo"in headline)# Trueprint("Wenda"in headline)# Falseprint(headline.find("Waldo"))# 8print(headline.find("Wenda"))# -1Con la tecnología de
Búsqueda acotada con start y end
El final es exclusivo, por lo que las posiciones de búsqueda reflejan la semántica de los cortes.
headline ="Where's Waldo?"print(headline.find("Waldo",0,6))# -1 (buscando en "Where'")print(headline.find("Waldo",0,13))# 8 (buscando hasta la 'o' de Waldo)Con la tecnología de
Contar y sustituir
inventory ="apple, apple, pear, apple"print(inventory.count("apple"))# 3print(inventory.replace("apple","orange",2))# orange, orange, pear, appleCon la tecnología de
Ejemplo de práctica de búsqueda y sustitución de cadenas en Python
Este ejemplo procesa una lista de reseñas de películas. Demuestra comprobaciones de existencia, búsquedas acotadas y sustituciones seguras sin 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)Con la tecnología de
Salida:
Window check: actor not found
Fans argue the actor scene was intentionally repetitive.
Window check: actor not foundCon la tecnología de
Conclusión
Usa el operador in para comprobaciones simples de contención, .find() o .index() cuando necesites posiciones, .count() para recuentos no solapados y .replace() para sustituciones. Normaliza con .casefold() para comprobaciones sin distinguir mayúsculas y, cuando proceda, prefiere los ayudantes específicos de prefijo/sufijo. Evitamos convertir los resultados de .find() a booleanos y tratamos el comportamiento con la subcadena vacía como un caso especial para mantener el código de cadenas correcto y claro.
En este tutorial, aprenderás todo sobre las cadenas de Python: trocearlas y encadenarlas, manipularlas y darles formato con la clase Formatter, cadenas f, plantillas y ¡mucho más!
Es habitual recurrir a
.find()o.index()para comprobar si un texto existe en una cadena y encontrarse con comportamientos raros como unValueErroro pasar por alto una coincidencia al inicio de la cadena. La sensibilidad a mayúsculas y minúsculas, los límites de corte desfasados y el hecho de questrno tenga un método.contains()aumentan la confusión. La solución es sencilla: usa la herramienta adecuada. Para comprobar existencia, nos apoyamos en el operadorin; para posiciones, en.find()/.index(); para recuentos, en.count(); y para sustituciones, en.replace(), además de algunas técnicas seguras con Unicode cuando importa la insensibilidad a mayúsculas.Cómo gestiona Python la búsqueda de subcadenas
Las cadenas de texto en Python son Unicode. Las operaciones con subcadenas distinguen mayúsculas por defecto y están implementadas en C para ser rápidas. La forma más directa de comprobar si un texto aparece dentro de una cadena es el operador
in, que devuelve un booleano usando la implementación__contains__()de la cadena. Cuando necesites posiciones o recuentos, usa los métodos específicos destr. Los parámetros opcionalesstartyendsiguen la semántica de los cortes: el inicio es inclusivo y el final, exclusivo.Contención con in
Usa
"needle" in haystackcuando solo te importe si la subcadena existe. Es legible y evita manejar índices.Para comprobaciones sin distinguir mayúsculas, normaliza ambos lados.
.casefold()es más consciente de Unicode que.lower()y es mi opción por defecto para comparaciones sin mayúsculas."" in ssiempre esTrue(la cadena vacía está en todas las cadenas).Método str.find()
Sintaxis
str.find()devuelve el índice más bajo de la subcadena o-1si no se encuentra. Los parámetros opcionalesstartyendacotan la búsqueda.Ejemplos y casos de uso
Usa
.find()cuando necesites la posición y puedas gestionar un "no encontrado" sin excepciones.No escribas
if s.find(sub):para comprobar existencia. Si la coincidencia está en el índice 0, la condición es falsy.Método str.index()
Sintaxis
.index()refleja a.find()pero lanzaValueErrorcuando la subcadena no existe.Ejemplos y cuándo elegirlo
Usa
.index()cuando la subcadena debe existir y una excepción sea la forma adecuada de fallar.Método str.count()
Sintaxis
.count()devuelve el número de apariciones no solapadas. También acepta límitesstartyend.Ejemplos y casos límite
Usa
.count()para recuentos rápidos sin regex.Caso especial: la cadena vacía.
Método str.replace()
.replace()devuelve una cadena nueva donde las apariciones deoldse sustituyen pornew. Usacountpara limitar sustituciones.Sustituir subcadenas
El método no es in-place; devuelve una copia.
Sustitución sin distinguir mayúsculas
Para sustituciones sin distinguir mayúsculas conservando los patrones de capitalización, usa
re.sub()conre.IGNORECASE, o normaliza con.casefold()si no necesitas preservar el formato original.Coincidencias sin distinguir mayúsculas con .casefold()
.casefold()ofrece una normalización agresiva y consciente de Unicode y se prefiere frente a.lower()para comprobaciones sin mayúsculas.Herramientas relacionadas para prefijos y sufijos
Si conoces el inicio o el final, usa métodos específicos: son más rápidos y claros que cortar o usar regex:
s.startswith(prefix)ys.endswith(suffix)(aceptan tuplas para múltiples opciones)s.removeprefix(prefix)ys.removesuffix(suffix)(Python 3.9+)Trabajar con columnas de pandas
Al buscar en muchas cadenas de una columna de DataFrame, usa los métodos vectorizados de cadenas. Establece
regex=Falsepara hacer coincidencias literales.Notas:
regex=True, así que caracteres especiales como.coinciden con cualquier carácter si no desactivas regex.na=.... ConStringDtype, los valores ausentes se convierten por defecto enFalseen la máscara.Errores comunes y casos límite
No existe .contains() en str: usa
"sub" in s."abc".contains("a")lanzaAttributeError.Veracidad de .find(): el índice
0es falsy; compara con!= -1o mejor usainpara existencia..index() lanza excepciones: gestiona
ValueErrorsi la subcadena podría no estar.Cadena vacía:
"" in sesTrue;s.find("")devuelve0;s.count("")eslen(s)+1.Sensibilidad a mayúsculas: todas las operaciones distinguen mayúsculas salvo que normalices o uses flags de regex.
Bytes vs. texto: no mezcles
bytesystren búsquedas; decodifica o codifica para igualar tipos.Semántica de subcadenas:
"ab" in "cat,bat"esFalseaunque"a"y"b"aparezcan por separado: las coincidencias deben ser contiguas.Ejemplos prácticos para ejecutar
Estos fragmentos cortos muestran patrones correctos y señalan tropiezos habituales.
Comprobaciones de existencia
Búsqueda acotada con start y end
El final es exclusivo, por lo que las posiciones de búsqueda reflejan la semántica de los cortes.
Contar y sustituir
Ejemplo de práctica de búsqueda y sustitución de cadenas en Python
Este ejemplo procesa una lista de reseñas de películas. Demuestra comprobaciones de existencia, búsquedas acotadas y sustituciones seguras sin regex.
Salida:
Conclusión
Usa el operador
inpara comprobaciones simples de contención,.find()o.index()cuando necesites posiciones,.count()para recuentos no solapados y.replace()para sustituciones. Normaliza con.casefold()para comprobaciones sin distinguir mayúsculas y, cuando proceda, prefiere los ayudantes específicos de prefijo/sufijo. Evitamos convertir los resultados de.find()a booleanos y tratamos el comportamiento con la subcadena vacía como un caso especial para mantener el código de cadenas correcto y claro.