Conversão para Snake Case em Python

Beginner

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

Introdução

No Python, o snake case é uma convenção de nomenclatura onde as palavras são separadas por underscores (sublinhados). Este estilo de nomenclatura é comumente usado para variáveis, funções e outros identificadores em Python. Por exemplo, calculate_total_price e user_authentication estão no formato snake case.

Às vezes, podemos encontrar strings que estão em formatos diferentes, como camelCase, PascalCase, ou até mesmo strings com espaços e hífens. Em tais situações, precisamos converter essas strings para snake case para consistência em nosso código.

Neste laboratório, você aprenderá como escrever uma função Python que converte strings de vários formatos para snake case.

Compreendendo o Problema

Antes de escrever nossa função de conversão para snake case, vamos entender o que precisamos realizar:

  1. Precisamos converter uma string de qualquer formato para snake case.
  2. Snake case significa todas as letras minúsculas com underscores (sublinhados) entre as palavras.
  3. Precisamos lidar com diferentes formatos de entrada:
    • camelCase (por exemplo, camelCasecamel_case)
    • Strings com espaços (por exemplo, some textsome_text)
    • Strings com formatação mista (por exemplo, hífens, underscores e letras maiúsculas e minúsculas misturadas)

Vamos começar criando um novo arquivo Python para nossa função snake case. No WebIDE, navegue até o diretório do projeto e crie um novo arquivo chamado snake_case.py:

## Esta função converterá uma string para snake case
def snake(s):
    ## Implementaremos esta função passo a passo
    pass  ## Placeholder (espaço reservado) por enquanto

## Teste com um exemplo simples
if __name__ == "__main__":
    test_string = "helloWorld"
    result = snake(test_string)
    print(f"Original: {test_string}")
    print(f"Snake case: {result}")

Salve este arquivo. No próximo passo, começaremos a implementar a função.

Por enquanto, vamos executar nossa função placeholder para garantir que nosso arquivo esteja configurado corretamente. Abra um terminal e execute:

python3 ~/project/snake_case.py
python-prompt

Você deve ver uma saída como:

Original: helloWorld
Snake case: None

O resultado é None porque nossa função está atualmente apenas retornando o valor padrão None do Python. No próximo passo, adicionaremos a lógica de conversão real.

Usando Expressões Regulares para Correspondência de Padrões

Para converter strings para snake case, usaremos expressões regulares (regex) para identificar limites de palavras. O módulo re no Python fornece recursos poderosos de correspondência de padrões que podemos usar para esta tarefa.

Vamos atualizar nossa função para lidar com strings camelCase:

  1. Primeiro, precisamos identificar o padrão onde uma letra minúscula é seguida por uma letra maiúscula (como em "camelCase")
  2. Em seguida, inseriremos um espaço entre elas
  3. Finalmente, converteremos tudo para minúsculas e substituiremos os espaços por underscores

Atualize seu arquivo snake_case.py com esta função aprimorada:

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}")

Vamos detalhar o que esta função faz:

  • re.sub('([a-z])([A-Z])', r'\1 \2', s) procura padrões onde uma letra minúscula ([a-z]) é seguida por uma letra maiúscula ([A-Z]). Em seguida, substitui este padrão pelas mesmas letras, mas adiciona um espaço entre elas usando \1 e \2, que se referem aos grupos capturados.
  • Então, convertemos tudo para minúsculas com lower() e substituímos os espaços por underscores.

Execute seu script novamente para ver se ele funciona para camelCase:

python3 ~/project/snake_case.py

A saída agora deve ser:

Original: helloWorld
Snake case: hello_world

Ótimo! Nossa função agora pode lidar com strings camelCase. No próximo passo, vamos aprimorá-la para lidar com casos mais complexos.

Lidando com Padrões Mais Complexos

Nossa função atual funciona para camelCase, mas precisamos aprimorá-la para lidar com padrões adicionais como:

  1. PascalCase (por exemplo, HelloWorld)
  2. Strings com hífens (por exemplo, hello-world)
  3. Strings que já possuem underscores (por exemplo, hello_world)

Vamos atualizar nossa função para lidar com esses casos:

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)

Os aprimoramentos que fizemos:

  1. Primeiro, substituímos quaisquer hífens por espaços.
  2. A nova regex re.sub('([A-Z]+)', r' \1', s) adiciona um espaço antes de qualquer sequência de letras maiúsculas, o que ajuda com PascalCase.
  3. Mantemos nossa regex de tratamento camelCase.
  4. Finalmente, dividimos a string por espaços, juntamos com underscores e convertemos para minúsculas, o que lida com quaisquer espaços restantes e garante uma saída consistente.

Execute seu script para testar com vários formatos de entrada:

python3 ~/project/snake_case.py

Você deve ver uma saída como:

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
--------------------

Nossa função agora é mais robusta e pode lidar com vários formatos de entrada. No próximo passo, faremos nossos refinamentos finais e testaremos em relação ao conjunto completo de testes.

Implementação Final e Testes

Agora, vamos completar nossa implementação para lidar com todos os casos necessários e verificar se ela passa em todos os casos de teste.

Atualize seu arquivo snake_case.py com a implementação final:

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}")

Esta implementação final:

  1. Substitui hífens por espaços
  2. Adiciona um espaço antes de padrões como "Word" com re.sub('([A-Z][a-z]+)', r' \1', s)
  3. Adiciona um espaço antes de sequências de letras maiúsculas com re.sub('([A-Z]+)', r' \1', s)
  4. Divide por espaços, junta com underscores e converte para minúsculas

Agora, vamos executar nossa função em relação ao conjunto de testes que foi criado na etapa de configuração:

python3 ~/project/test_snake.py

Se sua implementação estiver correta, você deverá ver:

All tests passed! Your snake case function works correctly.

Parabéns! Você implementou com sucesso uma função robusta de conversão para snake case que pode lidar com vários formatos de entrada.

Vamos garantir que nossa função siga com precisão a especificação, testando-a com os exemplos do problema 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)

Execute seu script atualizado:

python3 ~/project/snake_case.py

Você deve ver que todos os exemplos são convertidos corretamente para 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
--------------------

Resumo

Neste laboratório, você aprendeu a criar uma função Python que converte strings de vários formatos para snake case. Aqui está o que você realizou:

  1. Você aprendeu como expressões regulares podem ser usadas para correspondência de padrões e transformação de strings
  2. Você implementou uma função que pode lidar com diferentes formatos de entrada:
    • camelCase (por exemplo, camelCasecamel_case)
    • PascalCase (por exemplo, HelloWorldhello_world)
    • Strings com espaços (por exemplo, some textsome_text)
    • Strings com hífens (por exemplo, hello-worldhello_world)
    • Formatos mistos com vários delimitadores e capitalização

As principais técnicas que você usou:

  • Expressões regulares com grupos de captura usando re.sub()
  • Métodos de string como replace(), lower(), split() e join()
  • Reconhecimento de padrões para diferentes convenções de nomenclatura

Essas habilidades são valiosas para limpeza de dados, processamento de entrada de texto e manutenção de padrões de codificação consistentes. A capacidade de converter entre diferentes formatos de caixa (case) é particularmente útil ao trabalhar com APIs ou bibliotecas que usam diferentes convenções de nomenclatura.