Konvertieren von Snake Case in Lower Camel Case (lowerCamelCase)

79

Was wäre ein guter Weg, um my_stringin Python 2.7 von Snake Case ( ) in Lower Camel Case (myString) zu konvertieren ?

Die naheliegende Lösung besteht darin, durch Unterstrich zu teilen, jedes Wort außer dem ersten groß zu schreiben und wieder zusammenzufügen.

Ich bin jedoch neugierig auf andere, idiomatischere Lösungen oder einen Weg, dies RegExpzu erreichen (mit einigen Fallmodifikatoren?).

luca
quelle
Meines Wissens gibt es nichts, was dies sofort erreichen könnte. Haben Sie versucht, Ihre eigene Lösung zu implementieren?
Frédéric Hamidi
bearbeitet meine Frage, ich weiß, es gibt keine eingebaute, ich wollte eine schöne Implementierung finden
luca
Ich denke nicht, dass diese Frage in irgendeiner Weise "off topic" ist.
0xc0de

Antworten:

141
def to_camel_case(snake_str):
    components = snake_str.split('_')
    # We capitalize the first letter of each component except the first one
    # with the 'title' method and join them together.
    return components[0] + ''.join(x.title() for x in components[1:])

Beispiel:

In [11]: to_camel_case('snake_case')
Out[11]: 'snakeCase'
jbaiter
quelle
11
Auf welche anderen Datataypes wäre camelCasing anwendbar?
Jbaiter
20
Nun, das ist kein wirklich idiomatisches Python, das im Allgemeinen dem Prinzip "Einfacher um Vergebung als um Erlaubnis zu bitten" folgt. Mit> 3.5 können Sie Typhinweise hinzufügen, wenn Sie Typensicherheit wünschen, aber die Typprüfung mit if-else für Funktionen durchzuführen, die so eindeutig sind wie diese (was könnten Sie anders als Zeichenfolgen für camelCase tun?), Ist nur ein schlechter Stil und übertrieben Ausführlichkeit in meinem Buch.
Jbaiter
2
Ich wollte hier nur den zweiten Jbaiter machen. Es liegt nicht in der Verantwortung to_camel_casesicherzustellen, dass die Eingabe eine Zeichenfolge ist, sondern in der Verantwortung, Code aufzurufen. Das Übergeben eines Nicht-Strings löst eine Ausnahme aus, was gut ist. Dafür gibt es Ausnahmen.
Kylebebak
@stelios Nicht einmal. Was ist mit leeren Strings? Und was würden Sie sonst tun? Weil du also a zurückgibst None. Sie können keinen einzelnen Fehler verhindern. Wenn Sie es versuchen, werden Sie nur die Quelle beschatten. Das ist Python, nicht Java. Sie müssen Ausnahmen nicht vermeiden, Sie müssen sie behandeln.
Nuno André
1
Ein bisschen wie ein _barbarBarcomponents = snake_str.lstrip('_').split('_')
Eckfall
15

Hier ist noch eine weitere Einstellung, die nur in Python 3.5 und höher funktioniert:

def camel(snake_str):
    first, *others = snake_str.split('_')
    return ''.join([first.lower(), *map(str.title, others)])
Berislav Lopac
quelle
Verwenden Sie das Listenverständnis nicht, wenn ein Generator dies tun würde (dh es join(...)ist besser als join([...])hier, da es funktioniert, ohne eine Liste zu erstellen).
Vedran Šego
2
Sie haben absolut Recht, dies gilt jedoch in diesem speziellen Fall nicht, da das, was an die joinMethode übergeben wird, kein Verständnis, sondern eine reguläre Liste ist. Wenn Sie vermeiden möchten, eine In-Memory-Liste zu erstellen, können Sie diese verwenden itertools.chain. Wenn Sie jedoch Bedenken hinsichtlich des Speicherbedarfs bei der Konvertierung von Snake in Camel Case haben, haben Sie viel größere Probleme. ;-)
Berislav Lopac
Entschuldigung, ich habe es falsch verstanden (weil ich hier nach dem PascalCase anstelle von camelCase gesucht habe). Nein, das ist in Ordnung.
Vedran Šego
7

Obligatorischer Einzeiler:

import string

def to_camel_case(s):
    return s[0].lower() + string.capwords(s, sep='_').replace('_', '')[1:] if s else s
Simeon Visser
quelle
Diese Methode schlägt fehl, wenn ein führender Unterstrich vorhanden ist (der erste Buchstabe wird weggelassen).
siebz0r
3
Noch kürzer: return re.sub(r'_([a-z])', lambda x: x.group(1).upper(), name) (siehe hier)
Mathieu Rodic
5
>>> snake_case = "this_is_a_snake_case_string"
>>> l = snake_case.split("_")
>>> print l[0] + "".join(map(str.capitalize, l[1:]))
'thisIsASnakeCaseString'
Leon Young
quelle
4

ein anderer Liner

def to_camel_case(snake_string):
    return snake_string.title().replace("_", "")
Steve
quelle
3
Das erste Zeichen ist Großbuchstaben.
SiHa
3

Ein bisschen spät dran, aber ich habe das vor ein paar Tagen auf / r / python gefunden:

pip install pyhumps

und dann können Sie einfach tun:

import humps

humps.camelize('jack_in_the_box')  # jackInTheBox
# or
humps.decamelize('rubyTuesdays')  # ruby_tuesdays
# or
humps.pascalize('red_robin')  # RedRobin
Glenn Dills
quelle
1

Aufbauend auf Steves Antwort sollte diese Version funktionieren:

def to_camel_case(snake_case_string):
    titleCaseVersion =  snake_case_string.title().replace("_", "")
    camelCaseVersion = titleCaseVersion[0].lower() + titleCaseVersion[1:]
    return camelCaseVersion
MLev
quelle
1

Hier ist eine Lösung mit regulären Ausdrücken:

import re

def snake_to_camel(text):
    return re.sub('_([a-zA-Z0-9])', lambda m: m.group(1).upper(), text)
Antoine Pinsard
quelle
0
def to_camel_case(snake_str):
    components = snake_str.split('_')
    return reduce(lambda x, y: x + y.title(), components[1:], components[0])
Chandler Childs
quelle
0

Ohne Listenverständnis zu verwenden:

def snake_to_camel_case(text_snake):
    return '{}{}'.format(
        text_snake[:1].lower(),
        text_snake.title().replace('_', '')[1:],
    )
Michael Thiesen
quelle
0

Also musste ich eine ganze Datei mit einer Reihe von Schlangenfallparametern in einen Kamelfall konvertieren. Die Lösung von Mathieu Rodic hat am besten funktioniert. Vielen Dank.

Hier ist ein kleines Skript, um es für Dateien zu verwenden.

import re

f = open("in.txt", "r")
words = f.read()

def to_camel_case3(s):
    return re.sub(r'_([a-z])', lambda x: x.group(1).upper(), s)

f = open("out.txt", "w")
f.write(to_camel_case3(words))
Mike Starov
quelle
0
def toCamel(snake)
    return ''.join( word.capitalize()
                    for word in snake.split('_') )

Lassen Sie zu, dass der Unterstrich durch einen vorhergehenden Unterstrich maskiert wird (z. B. 'Escaped__snake' wird zu 'Escaped_Snake', während 'usual_snake' zu 'UsualSnake' wird. Fügen Sie einen ternären Test für Leerzeichen hinzu.

def toCamel(escaped_snake)
    return ''.join( (word.capitalize(), '_')[word=='')
                    for word in escaped_snake.split('_') )

Großschreibung des 1. Segments nicht (dh 'tHERE_is_a_snake' wird zu 'thereIsASnake')

def toCamel(esCAPed_snake)
    words = esCAPed_snake.split('_')
    return words[0].lower() + ''.join( (word.capitalize(), '_')[word=='')
                                       for word in words[1:] )
Gesegneter Geek
quelle
-2

Es gibt auch tocamelcaseleicht von Schlangenkoffer zu Kamelkoffer zu konvertieren.

Installieren

$ pip install tocamelcase

und dann können Sie es so verwenden:

import tocamelcase

print(tocamelcase.convert("non_camel_case"))
# -> non_camel_case → NonCamelCase

Es gibt auch decamelizedas Gegenteil dieses Moduls.

abranhe
quelle
Dies ist PascalCase, daher ist selbst der Modulname irreführend.
stasdeep