332 Stimmen

Elegante Python-Funktion zur Umwandlung von CamelCase in snake_case?

Exemple :

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

1174voto

epost Punkte 51

Kamelkoffer zu Schlangenkoffer

import re

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

Wenn Sie dies oft tun und der obige Vorgang langsam ist, kompilieren Sie die Regex vorher:

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

Speziell für fortgeschrittene Fälle (dies ist nicht mehr umkehrbar):

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

Um auch Fälle mit zwei oder mehr Unterstrichen hinzuzufügen:

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

Schlangenkoffer zu Kamelkoffer

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

305voto

Brad Koch Punkte 17657

Es gibt eine Beugungsbibliothek im Paketindex, die diese Dinge für Sie erledigen können. In diesem Fall würden Sie suchen nach inflection.underscore() :

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

156voto

nickl- Punkte 7591

Ich weiß nicht, warum das alles so kompliziert ist.

Für die meisten Fälle gilt der einfache Ausdruck ([A-Z]+) wird den Zweck erfüllen

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

Um das erste Zeichen zu ignorieren, fügen Sie einfach look hinter (?!^)

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

Wenn Sie ALLCaps in all_caps trennen wollen und Zahlen in Ihrer Zeichenkette erwarten, brauchen Sie trotzdem nicht zwei separate Durchläufe zu machen, sondern verwenden Sie | Dieser Ausdruck ((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z])) kann so gut wie jedes denkbare Szenario bewältigen

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

Es hängt alles davon ab, was Sie wollen, also verwenden Sie die Lösung, die Ihren Bedürfnissen am besten entspricht, denn sie sollte nicht übermäßig kompliziert sein.

nFreude!

96voto

otocan Punkte 571

Vermeidung von Bibliotheken und regulären Ausdrücken:

def camel_to_snake(s):
    return ''.join(['_'+c.lower() if c.isupper() else c for c in s]).lstrip('_')

>>> camel_to_snake('ThisIsMyString')
'this_is_my_string'

44voto

Beau Punkte 10809

stringcase ist meine bevorzugte Bibliothek für diese Zwecke; z.B.:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X