Conversion en snake case en Python

PythonPythonBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

En Python, le snake case est une convention de nommage où les mots sont séparés par des underscores (tirets bas). Ce style de nommage est couramment utilisé pour les variables, les fonctions et autres identifiants en Python. Par exemple, calculate_total_price et user_authentication sont au format snake case.

Parfois, nous pouvons rencontrer des chaînes de caractères dans différents formats comme le camelCase, le PascalCase, ou même des chaînes avec des espaces et des tirets. Dans de telles situations, nous devons convertir ces chaînes en snake case pour assurer la cohérence de notre code.

Dans ce lab (atelier), vous apprendrez à écrire une fonction Python qui convertit des chaînes de caractères de divers formats en snake case.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/AdvancedTopicsGroup(["Advanced Topics"]) python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python/BasicConceptsGroup -.-> python/strings("Strings") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/AdvancedTopicsGroup -.-> python/regular_expressions("Regular Expressions") subgraph Lab Skills python/strings -.-> lab-13716{{"Conversion en snake case en Python"}} python/function_definition -.-> lab-13716{{"Conversion en snake case en Python"}} python/regular_expressions -.-> lab-13716{{"Conversion en snake case en Python"}} end

Comprendre le problème

Avant d'écrire notre fonction de conversion en snake case, comprenons ce que nous devons accomplir :

  1. Nous devons convertir une chaîne de caractères de n'importe quel format en snake case.
  2. Le snake case signifie que toutes les lettres sont en minuscules et que les mots sont séparés par des underscores (tirets bas).
  3. Nous devons gérer différents formats d'entrée :
    • Le camelCase (par exemple, camelCasecamel_case)
    • Les chaînes avec des espaces (par exemple, some textsome_text)
    • Les chaînes avec un formatage mixte (par exemple, des tirets, des underscores et des majuscules et minuscules mélangées)

Commençons par créer un nouveau fichier Python pour notre fonction de snake case. Dans le WebIDE, accédez au répertoire du projet et créez un nouveau fichier appelé snake_case.py :

## Cette fonction convertira une chaîne de caractères en snake case
def snake(s):
    ## Nous allons implémenter cette fonction étape par étape
    pass  ## Placeholder pour l'instant

## Test avec un exemple simple
if __name__ == "__main__":
    test_string = "helloWorld"
    result = snake(test_string)
    print(f"Original: {test_string}")
    print(f"Snake case: {result}")

Enregistrez ce fichier. À l'étape suivante, nous allons commencer à implémenter la fonction.

Pour l'instant, exécutons notre fonction de placeholder pour nous assurer que notre fichier est correctement configuré. Ouvrez un terminal et exécutez :

python3 ~/project/snake_case.py
python-prompt

Vous devriez voir une sortie comme celle-ci :

Original: helloWorld
Snake case: None

Le résultat est None car notre fonction retourne actuellement simplement la valeur par défaut None de Python. À l'étape suivante, nous allons ajouter la logique de conversion réelle.

Utilisation des expressions régulières pour la correspondance de motifs

Pour convertir des chaînes de caractères en snake case, nous allons utiliser des expressions régulières (regex) pour identifier les limites des mots. Le module re en Python offre des capacités puissantes de correspondance de motifs que nous pouvons utiliser pour cette tâche.

Mettons à jour notre fonction pour gérer les chaînes au format camelCase :

  1. Tout d'abord, nous devons identifier le motif où une lettre minuscule est suivie d'une lettre majuscule (comme dans "camelCase").
  2. Ensuite, nous allons insérer un espace entre elles.
  3. Enfin, nous allons convertir tout en minuscules et remplacer les espaces par des underscores (tirets bas).

Mettez à jour votre fichier snake_case.py avec cette fonction améliorée :

import re

def snake(s):
    ## Replace pattern of a lowercase letter followed by uppercase with lowercase, space, uppercase
    s1 = re.sub('([a-z])([A-Z])', r'\1 \2', s)

    ## Replace spaces with underscores and convert to lowercase
    return s1.lower().replace(' ', '_')

## Test with a simple example
if __name__ == "__main__":
    test_string = "helloWorld"
    result = snake(test_string)
    print(f"Original: {test_string}")
    print(f"Snake case: {result}")

Analysons ce que fait cette fonction :

  • re.sub('([a-z])([A-Z])', r'\1 \2', s) recherche les motifs où une lettre minuscule ([a-z]) est suivie d'une lettre majuscule ([A-Z]). Ensuite, il remplace ce motif par les mêmes lettres mais ajoute un espace entre elles en utilisant \1 et \2 qui font référence aux groupes capturés.
  • Ensuite, nous convertissons tout en minuscules avec lower() et remplaçons les espaces par des underscores.

Exécutez votre script à nouveau pour voir si cela fonctionne pour les chaînes au format camelCase :

python3 ~/project/snake_case.py

La sortie devrait maintenant être :

Original: helloWorld
Snake case: hello_world

Génial ! Notre fonction peut maintenant gérer les chaînes au format camelCase. À l'étape suivante, nous allons la améliorer pour gérer des cas plus complexes.

Gestion de motifs plus complexes

Notre fonction actuelle fonctionne pour le camelCase, mais nous devons l'améliorer pour gérer des motifs supplémentaires tels que :

  1. Le PascalCase (par exemple, HelloWorld)
  2. Les chaînes avec des tirets (par exemple, hello-world)
  3. Les chaînes qui ont déjà des underscores (par exemple, hello_world)

Mettons à jour notre fonction pour gérer ces cas :

import re

def snake(s):
    ## Replace hyphens with spaces
    s = s.replace('-', ' ')

    ## Handle PascalCase pattern (sequences of uppercase letters)
    s = re.sub('([A-Z]+)', r' \1', s)

    ## Handle camelCase pattern (lowercase followed by uppercase)
    s = re.sub('([a-z])([A-Z])', r'\1 \2', s)

    ## Split by spaces, join with underscores, and convert to lowercase
    return '_'.join(s.split()).lower()

## Test with multiple examples
if __name__ == "__main__":
    test_strings = [
        "helloWorld",
        "HelloWorld",
        "hello-world",
        "hello_world",
        "some text"
    ]

    for test in test_strings:
        result = snake(test)
        print(f"Original: {test}")
        print(f"Snake case: {result}")
        print("-" * 20)

Les améliorations que nous avons apportées :

  1. Tout d'abord, nous remplaçons tous les tirets par des espaces.
  2. La nouvelle expression régulière re.sub('([A-Z]+)', r' \1', s) ajoute un espace avant toute séquence de lettres majuscules, ce qui aide pour le PascalCase.
  3. Nous conservons notre expression régulière de gestion du camelCase.
  4. Enfin, nous divisons la chaîne par les espaces, la rejoignons avec des underscores et la convertissons en minuscules, ce qui gère tous les espaces restants et assure une sortie cohérente.

Exécutez votre script pour tester avec différents formats d'entrée :

python3 ~/project/snake_case.py

Vous devriez voir une sortie comme celle-ci :

Original: helloWorld
Snake case: hello_world
--------------------
Original: HelloWorld
Snake case: hello_world
--------------------
Original: hello-world
Snake case: hello_world
--------------------
Original: hello_world
Snake case: hello_world
--------------------
Original: some text
Snake case: some_text
--------------------

Notre fonction est maintenant plus robuste et peut gérer différents formats d'entrée. À l'étape suivante, nous ferons nos derniers ajustements et testerons avec la suite de tests complète.

Implémentation finale et tests

Maintenant, terminons notre implémentation pour gérer tous les cas requis et vérifions qu'elle passe tous les cas de test.

Mettez à jour votre fichier snake_case.py avec l'implémentation finale :

import re

def snake(s):
    ## Replace hyphens with spaces
    s = s.replace('-', ' ')

    ## Handle PascalCase pattern
    s = re.sub('([A-Z][a-z]+)', r' \1', s)

    ## Handle sequences of uppercase letters
    s = re.sub('([A-Z]+)', r' \1', s)

    ## Split by whitespace and join with underscores
    return '_'.join(s.split()).lower()

## Test with a complex example
if __name__ == "__main__":
    test_string = "some-mixed_string With spaces_underscores-and-hyphens"
    result = snake(test_string)
    print(f"Original: {test_string}")
    print(f"Snake case: {result}")

Cette implémentation finale :

  1. Remplace les tirets par des espaces
  2. Ajoute un espace avant les motifs comme "Word" avec re.sub('([A-Z][a-z]+)', r' \1', s)
  3. Ajoute un espace avant les séquences de lettres majuscules avec re.sub('([A-Z]+)', r' \1', s)
  4. Divise la chaîne par les espaces, la rejoint avec des underscores et la convertit en minuscules

Maintenant, exécutons notre fonction avec la suite de tests créée à l'étape de configuration :

cd /tmp && python3 test_snake.py

Si votre implémentation est correcte, vous devriez voir :

All tests passed! Your snake case function works correctly.

Félicitations ! Vous avez réussi à implémenter une fonction de conversion en snake case robuste qui peut gérer différents formats d'entrée.

Vérifions que notre fonction suit précisément la spécification en la testant avec les exemples du problème original :

## Add this to the end of your snake_case.py file:
if __name__ == "__main__":
    examples = [
        'camelCase',
        'some text',
        'some-mixed_string With spaces_underscores-and-hyphens',
        'AllThe-small Things'
    ]

    for ex in examples:
        result = snake(ex)
        print(f"Original: {ex}")
        print(f"Snake case: {result}")
        print("-" * 20)

Exécutez votre script mis à jour :

python3 ~/project/snake_case.py

Vous devriez voir que tous les exemples sont correctement convertis en snake case :

Original: some-mixed_string With spaces_underscores-and-hyphens
Snake case: some_mixed_string_with_spaces_underscores_and_hyphens
Original: camelCase
Snake case: camel_case
--------------------
Original: some text
Snake case: some_text
--------------------
Original: some-mixed_string With spaces_underscores-and-hyphens
Snake case: some_mixed_string_with_spaces_underscores_and_hyphens
--------------------
Original: AllThe-small Things
Snake case: all_the_small_things
--------------------

Résumé

Dans ce laboratoire (lab), vous avez appris à créer une fonction Python qui convertit des chaînes de caractères de différents formats en snake case. Voici ce que vous avez accompli :

  1. Vous avez appris à utiliser les expressions régulières pour la correspondance de motifs et la transformation de chaînes de caractères.
  2. Vous avez implémenté une fonction capable de gérer différents formats d'entrée :
    • Le camelCase (par exemple, camelCasecamel_case)
    • Le PascalCase (par exemple, HelloWorldhello_world)
    • Les chaînes avec des espaces (par exemple, some textsome_text)
    • Les chaînes avec des tirets (par exemple, hello-worldhello_world)
    • Les formats mixtes avec différents délimiteurs et des règles de capitalisation variées.

Les techniques clés que vous avez utilisées :

  • Les expressions régulières avec des groupes de capture en utilisant re.sub()
  • Les méthodes de chaînes de caractères telles que replace(), lower(), split() et join()
  • La reconnaissance de motifs pour différentes conventions de nommage.

Ces compétences sont précieuses pour le nettoyage des données, le traitement des entrées textuelles et le maintien de normes de codage cohérentes. La capacité de convertir entre différents formats de cas est particulièrement utile lorsque vous travaillez avec des API ou des bibliothèques qui utilisent différentes conventions de nommage.