CamelCase를 snake_case로 변환하는 우아한 Python 함수? 개선하려면 기존

예:

>>> convert('CamelCase')
'camel_case'



답변

낙타 케이스에서 뱀 케이스로

import re

name = 'CamelCaseName'
name = re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
print(name)  # camel_case_name

이 작업을 여러 번 수행하고 위의 내용이 느리면 미리 정규 표현식을 컴파일하십시오.

pattern = re.compile(r'(?<!^)(?=[A-Z])')
name = pattern.sub('_', name).lower()

고급 사례를 특수하게 처리하려면 (더 이상 되돌릴 수 없습니다) :

def camel_to_snake(name):
  name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
  return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()

print(camel_to_snake('camel2_camel2_case'))  # camel2_camel2_case
print(camel_to_snake('getHTTPResponseCode'))  # get_http_response_code
print(camel_to_snake('HTTPResponseCodeXYZ'))  # http_response_code_xyz

뱀 케이스에서 낙타 케이스

name = 'snake_case_name'
name = ''.join(word.title() for word in name.split('_'))
print(name)  # SnakeCaseName


답변

패키지 인덱스에는 이러한 것들을 처리 할 수 있는 변곡 라이브러리 가 있습니다. 이 경우 다음을 찾고 있습니다 inflection.underscore().

>>> inflection.underscore('CamelCase')
'camel_case'


답변

왜 이것들이 그렇게 복잡한 지 모르겠습니다.

대부분의 경우 간단한 표현으로 ([A-Z]+)트릭을 수행합니다.

>>> re.sub('([A-Z]+)', r'_\1','CamelCase').lower()
'_camel_case'
>>> re.sub('([A-Z]+)', r'_\1','camelCase').lower()
'camel_case'
>>> re.sub('([A-Z]+)', r'_\1','camel2Case2').lower()
'camel2_case2'
>>> re.sub('([A-Z]+)', r'_\1','camelCamelCase').lower()
'camel_camel_case'
>>> re.sub('([A-Z]+)', r'_\1','getHTTPResponseCode').lower()
'get_httpresponse_code'

첫 번째 문자를 무시하려면 뒤에 외모를 추가하십시오. (?!^)

>>> re.sub('(?!^)([A-Z]+)', r'_\1','CamelCase').lower()
'camel_case'
>>> re.sub('(?!^)([A-Z]+)', r'_\1','CamelCamelCase').lower()
'camel_camel_case'
>>> re.sub('(?!^)([A-Z]+)', r'_\1','Camel2Camel2Case').lower()
'camel2_camel2_case'
>>> re.sub('(?!^)([A-Z]+)', r'_\1','getHTTPResponseCode').lower()
'get_httpresponse_code'

ALLCap을 all_caps로 분리하고 문자열에서 숫자를 기대하려면 여전히 두 개의 개별 런을 수행 할 필요가 없습니다. |이 표현식 ((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))은 책의 모든 시나리오를 처리 할 수 ​​있습니다.

>>> a = re.compile('((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))')
>>> a.sub(r'_\1', 'getHTTPResponseCode').lower()
'get_http_response_code'
>>> a.sub(r'_\1', 'get2HTTPResponseCode').lower()
'get2_http_response_code'
>>> a.sub(r'_\1', 'get2HTTPResponse123Code').lower()
'get2_http_response123_code'
>>> a.sub(r'_\1', 'HTTPResponseCode').lower()
'http_response_code'
>>> a.sub(r'_\1', 'HTTPResponseCodeXYZ').lower()
'http_response_code_xyz'

그것은 모두 당신이 원하는 것에 달려 있으므로 지나치게 복잡해서는 안되므로 귀하의 요구에 가장 적합한 솔루션을 사용하십시오.

조이!


답변

stringcase 는 이것에 대한 나의 도서관입니다. 예 :

>>> from stringcase import pascalcase, snakecase
>>> snakecase('FooBarBaz')
'foo_bar_baz'
>>> pascalcase('foo_bar_baz')
'FooBarBaz'


답변

개인적으로 파이썬에서 정규 표현식을 사용하는 것이 어떻게 우아하게 묘사 될 수 있는지 잘 모르겠습니다. 여기서 대부분의 답변은 “코드 골프”유형 RE 트릭을 수행하는 것입니다. 우아한 코딩은 쉽게 이해할 수 있어야합니다.

def to_snake_case(not_snake_case):
    final = ''
    for i in xrange(len(not_snake_case)):
        item = not_snake_case[i]
        if i < len(not_snake_case) - 1:
            next_char_will_be_underscored = (
                not_snake_case[i+1] == "_" or
                not_snake_case[i+1] == " " or
                not_snake_case[i+1].isupper()
            )
        if (item == " " or item == "_") and next_char_will_be_underscored:
            continue
        elif (item == " " or item == "_"):
            final += "_"
        elif item.isupper():
            final += "_"+item.lower()
        else:
            final += item
    if final[0] == "_":
        final = final[1:]
    return final

>>> to_snake_case("RegularExpressionsAreFunky")
'regular_expressions_are_funky'

>>> to_snake_case("RegularExpressionsAre Funky")
'regular_expressions_are_funky'

>>> to_snake_case("RegularExpressionsAre_Funky")
'regular_expressions_are_funky'


답변

re가능 하면 피하는 것이 좋습니다.

def to_camelcase(s):
    return ''.join(['_' + c.lower() if c.isupper() else c for c in s]).lstrip('_')
>>> to_camelcase("ThisStringIsCamelCase")
'this_string_is_camel_case'


답변

''.join('_'+c.lower() if c.isupper() else c for c in "DeathToCamelCase").strip('_')
re.sub("(.)([A-Z])", r'\1_\2', 'DeathToCamelCase').lower()