Python Snake Case 변환

Beginner

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

소개

Python 에서 snake case 는 단어 사이에 밑줄 (_) 을 사용하는 명명 규칙입니다. 이 명명 스타일은 Python 에서 변수, 함수 및 기타 식별자에 일반적으로 사용됩니다. 예를 들어, calculate_total_priceuser_authentication은 snake case 형식입니다.

때로는 camelCase, PascalCase 와 같은 다른 형식의 문자열이나 공백과 하이픈이 있는 문자열을 접할 수 있습니다. 이러한 상황에서는 코드의 일관성을 위해 이러한 문자열을 snake case 로 변환해야 합니다.

이 Lab 에서는 다양한 형식의 문자열을 snake case 로 변환하는 Python 함수를 작성하는 방법을 배우게 됩니다.

문제 이해

snake case 변환 함수를 작성하기 전에, 우리가 무엇을 달성해야 하는지 이해해 봅시다:

  1. 어떤 형식의 문자열이든 snake case 로 변환해야 합니다.
  2. Snake case 는 단어 사이에 밑줄이 있는 소문자를 의미합니다.
  3. 다양한 입력 형식을 처리해야 합니다:
    • camelCase (예: camelCasecamel_case)
    • 공백이 있는 문자열 (예: some textsome_text)
    • 혼합된 형식의 문자열 (예: 하이픈, 밑줄 및 대소문자 혼합)

snake case 함수를 위해 새로운 Python 파일을 만들어 보겠습니다. WebIDE 에서 프로젝트 디렉토리로 이동하여 snake_case.py라는 새 파일을 만듭니다:

## This function will convert a string to snake case
def snake(s):
    ## We'll implement this function step by step
    pass  ## Placeholder for now

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

이 파일을 저장합니다. 다음 단계에서는 함수를 구현하기 시작합니다.

지금은 파일이 올바르게 설정되었는지 확인하기 위해 자리 표시자 함수를 실행해 보겠습니다. 터미널을 열고 다음을 실행합니다:

python3 ~/project/snake_case.py
python-prompt

다음과 같은 출력이 표시되어야 합니다:

Original: helloWorld
Snake case: None

결과가 None인 이유는 현재 함수가 기본 Python None 값을 반환하기 때문입니다. 다음 단계에서는 실제 변환 로직을 추가합니다.

정규 표현식 (Regular Expressions) 을 사용한 패턴 매칭

문자열을 snake case 로 변환하기 위해 정규 표현식 (regex) 을 사용하여 단어 경계를 식별합니다. Python 의 re 모듈은 이 작업에 사용할 수 있는 강력한 패턴 매칭 기능을 제공합니다.

camelCase 문자열을 처리하도록 함수를 업데이트해 보겠습니다:

  1. 먼저 소문자 뒤에 대문자가 오는 패턴 (예: "camelCase") 을 식별해야 합니다.
  2. 그런 다음 그 사이에 공백을 삽입합니다.
  3. 마지막으로 모든 문자를 소문자로 변환하고 공백을 밑줄로 바꿉니다.

snake_case.py 파일을 이 개선된 함수로 업데이트하십시오:

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

이 함수가 수행하는 작업을 자세히 살펴보겠습니다:

  • re.sub('([a-z])([A-Z])', r'\1 \2', s)는 소문자 ([a-z]) 뒤에 대문자 ([A-Z])가 오는 패턴을 찾습니다. 그런 다음 이 패턴을 동일한 문자로 바꾸지만 캡처된 그룹을 참조하는 \1\2를 사용하여 그 사이에 공백을 추가합니다.
  • 그런 다음 lower()를 사용하여 모든 문자를 소문자로 변환하고 공백을 밑줄로 바꿉니다.

스크립트를 다시 실행하여 camelCase 에 대해 작동하는지 확인하십시오:

python3 ~/project/snake_case.py

이제 출력은 다음과 같아야 합니다:

Original: helloWorld
Snake case: hello_world

훌륭합니다! 이제 함수가 camelCase 문자열을 처리할 수 있습니다. 다음 단계에서는 더 복잡한 경우를 처리하도록 개선할 것입니다.

더 복잡한 패턴 처리

현재 함수는 camelCase 에 대해 작동하지만, 다음과 같은 추가 패턴을 처리하도록 개선해야 합니다:

  1. PascalCase (예: HelloWorld)
  2. 하이픈이 있는 문자열 (예: hello-world)
  3. 이미 밑줄이 있는 문자열 (예: hello_world)

이러한 경우를 처리하도록 함수를 업데이트해 보겠습니다:

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)

우리가 한 개선 사항:

  1. 먼저 하이픈을 공백으로 바꿉니다.
  2. 새로운 정규 표현식 re.sub('([A-Z]+)', r' \1', s)는 PascalCase 에 도움이 되도록 대문자 시퀀스 앞에 공백을 추가합니다.
  3. camelCase 처리 정규 표현식을 유지합니다.
  4. 마지막으로, 문자열을 공백으로 분할하고, 밑줄로 결합하고, 소문자로 변환하여 남아있는 공백을 처리하고 일관된 출력을 보장합니다.

스크립트를 실행하여 다양한 입력 형식으로 테스트하십시오:

python3 ~/project/snake_case.py

다음과 같은 출력이 표시되어야 합니다:

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

이제 함수가 더 강력해졌으며 다양한 입력 형식을 처리할 수 있습니다. 다음 단계에서는 최종 개선 사항을 적용하고 전체 테스트 스위트에 대해 테스트할 것입니다.

최종 구현 및 테스트

이제 모든 필요한 경우를 처리하고 모든 테스트 케이스를 통과하는지 확인하기 위해 구현을 완료해 보겠습니다.

snake_case.py 파일을 최종 구현으로 업데이트하십시오:

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

이 최종 구현은 다음과 같습니다:

  1. 하이픈을 공백으로 바꿉니다.
  2. re.sub('([A-Z][a-z]+)', r' \1', s)를 사용하여 "Word"와 같은 패턴 앞에 공백을 추가합니다.
  3. re.sub('([A-Z]+)', r' \1', s)를 사용하여 대문자 시퀀스 앞에 공백을 추가합니다.
  4. 공백으로 분할하고, 밑줄로 결합하고, 소문자로 변환합니다.

이제 설정 단계에서 생성된 테스트 스위트에 대해 함수를 실행해 보겠습니다:

python3 ~/project/test_snake.py

구현이 올바르면 다음을 볼 수 있습니다:

All tests passed! Your snake case function works correctly.

축하합니다! 다양한 입력 형식을 처리할 수 있는 강력한 snake case 변환 함수를 성공적으로 구현했습니다.

함수가 원래 문제의 예제를 사용하여 사양을 정확하게 따르는지 확인해 보겠습니다:

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

업데이트된 스크립트를 실행하십시오:

python3 ~/project/snake_case.py

모든 예제가 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
--------------------

요약

이 랩에서는 다양한 형식의 문자열을 snake case 로 변환하는 Python 함수를 만드는 방법을 배웠습니다. 다음은 여러분이 달성한 내용입니다:

  1. 정규 표현식 (regular expression) 이 패턴 매칭 (pattern matching) 및 문자열 변환에 어떻게 사용될 수 있는지 배웠습니다.
  2. 다음과 같은 다양한 입력 형식을 처리할 수 있는 함수를 구현했습니다:
    • camelCase (예: camelCasecamel_case)
    • PascalCase (예: HelloWorldhello_world)
    • 공백이 있는 문자열 (예: some textsome_text)
    • 하이픈이 있는 문자열 (예: hello-worldhello_world)
    • 다양한 구분 기호와 대소문자를 사용하는 혼합 형식

사용된 주요 기술:

  • re.sub()를 사용한 캡처 그룹 (capture group) 이 있는 정규 표현식
  • replace(), lower(), split(), join()과 같은 문자열 메서드
  • 다양한 명명 규칙에 대한 패턴 인식

이러한 기술은 데이터 정리, 텍스트 입력 처리 및 일관된 코딩 표준 유지에 유용합니다. 서로 다른 케이스 형식 간에 변환하는 기능은 서로 다른 명명 규칙을 사용하는 API 또는 라이브러리를 사용할 때 특히 유용합니다.