Accéder au contenu principal

Recherche et remplacement de chaînes en Python : in, .find(), .index(), .count() et .replace()

Modèles pratiques pour rechercher, compter et remplacer des sous-chaînes en Python moderne.
Actualisé 19 sept. 2026  · 8 min lire

Explorer avec l’IA

ChatGPTClaudePerplexity

Il est courant d’utiliser .find() ou .index() pour vérifier si un texte existe dans une chaîne—puis de rencontrer des comportements déroutants comme un ValueError ou une correspondance manquée au début de la chaîne. La sensibilité à la casse, les bornes de tranche décalées d’un caractère, et l’absence de méthode .contains() sur str ajoutent à la confusion. Le remède est simple : utilisez l’outil adapté. Appuyez-vous sur l’opérateur in pour les vérifications d’existence, .find()/.index() pour les positions, .count() pour les décomptes et .replace() pour les remplacements—avec quelques techniques sûres pour l’Unicode lorsque l’insensibilité à la casse est importante.

Comment Python gère la recherche de sous-chaînes

Les chaînes de texte en Python sont en Unicode. Les opérations sur les sous-chaînes sont sensibles à la casse par défaut et implémentées en C pour la performance. La manière la plus directe de tester si un texte apparaît dans une chaîne est l’opérateur in, qui renvoie un booléen via l’implémentation __contains__() de la chaîne. Lorsque vous avez besoin de positions ou de décomptes, utilisez les méthodes dédiées de str. Les paramètres optionnels start et end suivent la sémantique des tranches : début inclusif ; fin exclusive.

Vérifier la présence avec in

Utilisez "needle" in haystack lorsque vous voulez seulement savoir si la sous-chaîne existe. C’est lisible et évite la gestion des index.

text = "Banana bread"
print("ban" in text)   # False (case-sensitive)
print("Ban" in text)   # True

Pour des vérifications insensibles à la casse, normalisez les deux côtés. .casefold() est plus conscient de l’Unicode que .lower() et c’est mon choix par défaut pour les comparaisons sans casse.

pattern = "ban"
print(pattern.casefold() in text.casefold())  # True
  • Quand l’utiliser : vérifications rapides d’existence, validation d’entrée, filtrage de listes.
  • Cas limite : "" in s renvoie toujours True (la chaîne vide est dans toute chaîne).

Méthode str.find()

Syntaxe

str.find() renvoie le plus petit index de la sous-chaîne, ou -1 si elle n’est pas trouvée. Les paramètres facultatifs start et end restreignent la recherche.

s.find(substring, start=0, end=len(s))

Exemples et cas d’usage

Utilisez .find() lorsque vous avez besoin de la position et pouvez gérer une valeur « non trouvée » sans exceptions.

tagline = "Ship fast. Fix faster."
print(tagline.find("fast"))         # 5
print(tagline.find("fast", 6))      # 16
print(tagline.find("slow"))         # -1

N’écrivez pas if s.find(sub): pour vérifier l’existence. Si la correspondance est à l’index 0, la condition est falsy.

name = "Alice"
if name.find("A"):         # Incorrect : 0 est falsy
    print("Found A")       # Ne s'exécutera pas
if name.find("A") != -1:   # Correct
    print("Found A")

Méthode str.index()

Syntaxe

.index() reflète .find() mais lève un ValueError lorsque la sous-chaîne est absente.

s.index(substring, start=0, end=len(s))

Exemples et quand la choisir

Utilisez .index() lorsque la sous-chaîne doit exister et qu’une exception est le bon mode d’échec.

product = "USB-C Cable"
print(product.index("Cable"))  # 6

try:
    product.index("HDMI")
except ValueError:
    print("Required label missing")

Méthode str.count()

Syntaxe

.count() renvoie le nombre d’occurrences non superposées. Elle accepte aussi des bornes start et end.

s.count(substring, start=0, end=len(s))

Exemples et cas limites

Utilisez .count() pour des décomptes rapides sans regex.

log_line = "ERROR: timeout. ERROR: retry. ERROR: gave up."
print(log_line.count("ERROR"))     # 3
print(log_line.count("WARN"))      # 0

Cas particulier : la chaîne vide.

print("abc".count(""))   # 4 (len(s) + 1)

Méthode str.replace()

.replace() renvoie une nouvelle chaîne où les occurrences de old sont remplacées par new. Utilisez count pour limiter le nombre de remplacements.

s.replace(old, new, count=-1)

Remplacer des sous-chaînes

La méthode n’agit pas en place ; elle renvoie une copie.

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 car

print(message.replace("house", "car", 2))
# The red car is between the blue car and the old house

Remplacement insensible à la casse

Pour des remplacements insensibles à la casse tout en préservant les motifs de casse, utilisez re.sub() avec re.IGNORECASE, ou normalisez avec .casefold() si vous n’avez pas besoin de préserver la casse d’origine.

Correspondances insensibles à la casse avec .casefold()

.casefold() offre une normalisation agressive et compatible Unicode de la casse, et est préférable à .lower() pour les vérifications sans casse.

query = "straße"           # German 'straße'
text  = "STRASSE und mehr" # Uppercase variant
print(query.casefold() in text.casefold())  # True

Outils associés pour préfixes et suffixes

Pour des débuts/fins connus, privilégiez les méthodes dédiées—elles sont plus rapides et plus claires que les tranches ou les regex :

  • s.startswith(prefix) et s.endswith(suffix) (acceptent des tuples pour plusieurs options)
  • s.removeprefix(prefix) et s.removesuffix(suffix) (Python 3.9+)
filename = "draft_report_v2.pdf"
print(filename.removeprefix("draft_"))  # report_v2.pdf
print(filename.endswith((".pdf", ".docx")))  # True

Travailler avec des colonnes Pandas

Lorsque vous cherchez dans de nombreuses chaînes d’une colonne de DataFrame, utilisez les méthodes de chaîne vectorisées. Définissez regex=False pour faire correspondre du texte littéral.

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]

Remarques :

  • Par défaut, regex=True, donc des caractères spéciaux comme . correspondent à n’importe quel caractère, sauf si vous désactivez les regex.
  • Gérez les valeurs nulles via na=.... Avec StringDtype, les valeurs manquantes valent False par défaut dans le masque.

Pièges courants et cas limites

  • Pas de .contains() sur str : utilisez "sub" in s. "abc".contains("a") lève AttributeError.

  • Véracité de .find() : l’index 0 est falsy ; comparez avec != -1 ou préférez in pour l’existence.

  • .index() lève une exception : gérez ValueError si la sous-chaîne peut être absente.

  • Chaîne vide : "" in s est True ; s.find("") renvoie 0 ; s.count("") vaut len(s)+1.

  • Sensibilité à la casse : toutes les opérations sont sensibles à la casse sauf si vous normalisez ou utilisez des indicateurs regex.

  • Octets vs texte : ne mélangez pas bytes et str dans les recherches ; décodez ou encodez pour faire correspondre les types.

  • Sémantique des sous-chaînes : "ab" in "cat,bat" vaut False même si "a" et "b" apparaissent séparément—les correspondances doivent être contiguës.

Exemples pratiques à exécuter

Ces courts extraits montrent les bons modèles et mettent en évidence les pièges classiques.

Vérifications d’existence

headline = "Where's Waldo?"
print("Waldo" in headline)          # True
print("Wenda" in headline)          # False
print(headline.find("Waldo"))       # 8
print(headline.find("Wenda"))       # -1

Recherche bornée avec start et end

La fin est exclusive, donc les positions de recherche reflètent la sémantique des tranches.

headline = "Where's Waldo?"
print(headline.find("Waldo", 0, 6))   # -1 (recherche dans "Where'")
print(headline.find("Waldo", 0, 13))  # 8  (recherche jusqu'au 'o' de Waldo)

Compter et remplacer

inventory = "apple, apple, pear, apple"
print(inventory.count("apple"))                # 3
print(inventory.replace("apple", "orange", 2)) # orange, orange, pear, apple

Exemple d’exercice : recherche et remplacement de chaînes en Python 

Cet exemple traite une liste de critiques de films. Il illustre les vérifications d’existence, les recherches bornées et des remplacements sûrs sans 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()
    if not 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)

Sortie :

Window check: actor not found
Fans argue the actor scene was intentionally repetitive.
Window check: actor not found

Conclusion

Utilisez l’opérateur in pour la simple appartenance, .find() ou .index() lorsque vous avez besoin des positions, .count() pour les décomptes non superposés et .replace() pour les substitutions. Normalisez avec .casefold() pour des vérifications insensibles à la casse, et préférez les aides dédiées aux préfixes/suffixes lorsque c’est pertinent. Évitez de convertir les résultats de .find() en booléens et traitez le comportement avec la sous-chaîne vide comme un cas particulier afin de garder un code sur les chaînes correct et clair.

Sujets
Python

Cours Python

Cours

Introduction à Python

4 h
7M
Apprenez les bases de l’analyse de données avec Python en quatre heures et explorez ses principaux packages.
Afficher les détailsRight Arrow
Commencer Le Cours
Voir plusRight Arrow