Elegancka funkcja Pythona do konwersji CamelCase na Snake case?

Przykład:

>>> convert('CamelCase')
'camel_case'
Author: Sridhar Ratnakumar, 2009-07-24

30 answers

To jest dość dokładne:

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

Działa z tymi wszystkimi (i nie szkodzi już-nie-cameled wersje):

>>> convert('CamelCase')
'camel_case'
>>> convert('CamelCamelCase')
'camel_camel_case'
>>> convert('Camel2Camel2Case')
'camel2_camel2_case'
>>> convert('getHTTPResponseCode')
'get_http_response_code'
>>> convert('get2HTTPResponseCode')
'get2_http_response_code'
>>> convert('HTTPResponseCode')
'http_response_code'
>>> convert('HTTPResponseCodeXYZ')
'http_response_code_xyz'

Lub jeśli masz zamiar nazwać to milionem razy, możesz wstępnie skompilować wyrażenia regularne:

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

Nie zapomnij zaimportować modułu wyrażenia regularnego

import re
 579
Author: epost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-21 08:38:17

W indeksie pakietów znajduje się biblioteka fleksyjna, która może obsłużyć te rzeczy za Ciebie. W tym przypadku szukałbyś inflection.underscore():

>>> inflection.underscore('CamelCase')
'camel_case'
 125
Author: Brad Koch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-26 19:34:34

Nie wiem, dlaczego to wszystko jest takie skomplikowane.

W większości przypadków proste wyrażenie ([A-Z]+) wykona sztuczkę

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

Aby zignorować pierwszy charachter wystarczy dodać look behind (?!^)

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

Jeśli chcesz oddzielić ALLCaps od all_caps i oczekiwać liczb w ciągu znaków, nadal nie musisz robić dwóch oddzielnych uruchomień, użyj {[5] } to wyrażenie ((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z])) może obsłużyć prawie każdy scenariusz w książce

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

Wszystko zależy od tego, co chcesz, więc użyj rozwiązanie, które najlepiej pasuje do Twoich potrzeb, ponieważ nie powinno być zbyt skomplikowane.

NJoy!
 77
Author: nickl-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-12 21:17:16

Osobiście nie jestem pewien, jak cokolwiek używając wyrażeń regularnych w Pythonie można opisać jako eleganckie. Większość odpowiedzi tutaj są po prostu robi "kod golf" Typ RE sztuczki. Eleganckie kodowanie ma być łatwo zrozumiałe.

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'
 16
Author: TehTris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-04 14:33:37
''.join('_'+c.lower() if c.isupper() else c for c in "DeathToCamelCase").strip('_')
re.sub("(.)([A-Z])", r'\1_\2', 'DeathToCamelCase').lower()
 8
Author: Jimmy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-24 01:48:27

Stringcase jest moją biblioteką do tego; np.:

>>> from stringcase import pascalcase, snakecase
>>> snakecase('FooBarBaz')
'foo_bar_baz'
>>> pascalcase('foo_bar_baz')
'FooBarBaz'
 6
Author: Beau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-05 23:42:51

Nie rozumiem, po co używać obu .wywołania sub ()? :) Nie jestem guru regex, ale uprościłem funkcję do tej, która jest odpowiednia dla moich pewnych potrzeb, po prostu potrzebowałem rozwiązania do konwersji camelCasedVars z żądania POST na vars_with_underscore:

def myFunc(...):
  return re.sub('(.)([A-Z]{1})', r'\1_\2', "iTriedToWriteNicely").lower()

To nie działa z takimi nazwami jak getHTTPResponse, bo słyszałem, że to zła konwencja nazewnictwa(powinno być jak getHttpResponse, to oczywiście, że o wiele łatwiej zapamiętać ten formularz).

 5
Author: desper4do,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-13 15:39:08

Oto moje rozwiązanie:

def un_camel(text):
    """ Converts a CamelCase name into an under_score name. 

        >>> un_camel('CamelCase')
        'camel_case'
        >>> un_camel('getHTTPResponseCode')
        'get_http_response_code'
    """
    result = []
    pos = 0
    while pos < len(text):
        if text[pos].isupper():
            if pos-1 > 0 and text[pos-1].islower() or pos-1 > 0 and \
            pos+1 < len(text) and text[pos+1].islower():
                result.append("_%s" % text[pos].lower())
            else:
                result.append(text[pos].lower())
        else:
            result.append(text[pos])
        pos += 1
    return "".join(result)

Wspiera te narożne sprawy omówione w komentarzach. Na przykład konwertuje getHTTPResponseCode na get_http_response_code tak, jak powinno.

 4
Author: Evan Fosmark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-24 02:15:24

Myślę, że to rozwiązanie jest prostsze niż poprzednie odpowiedzi:

import re

def convert (camel_input):
    words = re.findall(r'[A-Z]?[a-z]+|[A-Z]{2,}(?=[A-Z][a-z]|\d|\W|$)|\d+', camel_input)
    return '_'.join(map(str.lower, words))


# Let's test it
test_strings = [
    'CamelCase',
    'camelCamelCase',
    'Camel2Camel2Case',
    'getHTTPResponseCode',
    'get200HTTPResponseCode',
    'getHTTP200ResponseCode',
    'HTTPResponseCode',
    'ResponseHTTP',
    'ResponseHTTP2',
    'Fun?!awesome',
    'Fun?!Awesome',
    '10CoolDudes',
    '20coolDudes'
]
for test_string in test_strings:
    print(convert(test_string))

Które wyjście:

camel_case
camel_camel_case
camel_2_camel_2_case
get_http_response_code
get_200_http_response_code
get_http_200_response_code
http_response_code
response_http
response_http_2
fun_awesome
fun_awesome
10_cool_dudes
20_cool_dudes

Wyrażenie regularne pasuje do trzech wzorców:

  1. [A-Z]?[a-z]+: kolejne małe litery, które opcjonalnie zaczynają się od wielkiej litery.
  2. [A-Z]{2,}(?=[A-Z][a-z]|\d|\W|$): dwie lub więcej kolejnych wielkich liter. Używa lookahead, aby wykluczyć ostatnią wielką literę, jeśli po niej następuje mała litera.
  3. \d+: konsekutywne liczby.

Za pomocą re.findall otrzymujemy listę pojedynczych "słów", które można przekonwertować na małe litery i połączyć z podkreślnikami.

 4
Author: rspeed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 00:03:43

Dla Zabawy:

>>> def un_camel(input):
...     output = [input[0].lower()]
...     for c in input[1:]:
...             if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
...                     output.append('_')
...                     output.append(c.lower())
...             else:
...                     output.append(c)
...     return str.join('', output)
...
>>> un_camel("camel_case")
'camel_case'
>>> un_camel("CamelCase")
'camel_case'

Lub, bardziej dla Zabawy:

>>> un_camel = lambda i: i[0].lower() + str.join('', ("_" + c.lower() if c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" else c for c in i[1:]))
>>> un_camel("camel_case")
'camel_case'
>>> un_camel("CamelCase")
'camel_case'
 3
Author: gahooa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-24 01:27:37

Nie w bibliotece standardowej, ale znalazłem Ten skrypt , który wydaje się zawierać funkcje, których potrzebujesz.

 2
Author: Stefano Borini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-24 00:27:58

Nie jest to elegancka metoda, jest bardzo' niskopoziomową ' implementacją prostej maszyny stanowej (bitfield state machine), prawdopodobnie najbardziej anty pythonicznym trybem do rozwiązania tego problemu, jednak moduł re implementuje również zbyt złożoną maszynę stanową, aby rozwiązać to proste zadanie, więc myślę, że jest to dobre rozwiązanie.

def splitSymbol(s):
    si, ci, state = 0, 0, 0 # start_index, current_index 
    '''
        state bits:
        0: no yields
        1: lower yields
        2: lower yields - 1
        4: upper yields
        8: digit yields
        16: other yields
        32 : upper sequence mark
    '''
    for c in s:

        if c.islower():
            if state & 1:
                yield s[si:ci]
                si = ci
            elif state & 2:
                yield s[si:ci - 1]
                si = ci - 1
            state = 4 | 8 | 16
            ci += 1

        elif c.isupper():
            if state & 4:
                yield s[si:ci]
                si = ci
            if state & 32:
                state = 2 | 8 | 16 | 32
            else:
                state = 8 | 16 | 32

            ci += 1

        elif c.isdigit():
            if state & 8:
                yield s[si:ci]
                si = ci
            state = 1 | 4 | 16
            ci += 1

        else:
            if state & 16:
                yield s[si:ci]
            state = 0
            ci += 1  # eat ci
            si = ci   
        print(' : ', c, bin(state))
    if state:
        yield s[si:ci] 


def camelcaseToUnderscore(s):
    return '_'.join(splitSymbol(s)) 

Splitsymbol może parsować wszystkie typy przypadków: UpperSEQUENCEInterleaved, under_score, BIG_SYMBOLS i cammelCasedMethods

Mam nadzieję, że się przyda

 2
Author: jdavidls,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-17 00:55:12

Właśnie ukradłem to z fragmentów django. ref http://djangosnippets.org/snippets/585/

Pretty elegant

camelcase_to_underscore = lambda str: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', '_\\1', str).lower().strip('_')

Przykład:

camelcase_to_underscore('ThisUser')

Zwraca:

'this_user'
 1
Author: brianray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-18 19:05:44

Używanie wyrażeń regularnych może być najkrótsze, ale to rozwiązanie jest o wiele bardziej czytelne:

def to_snake_case(s):
    snake = "".join(["_"+c.lower() if c.isupper() else c for c in s])
    return snake[1:] if snake.startswith("_") else snake
 1
Author: 3k-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-27 21:39:18

Lekka adaptacja z https://stackoverflow.com/users/267781/matth którzy używają generatorów.

def uncamelize(s):
    buff, l = '', []
    for ltr in s:
        if ltr.isupper():
            if buff:
                l.append(buff)
                buff = ''
        buff += ltr
    l.append(buff)
    return '_'.join(l).lower()
 1
Author: Salvatore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:29

Spójrz na doskonałe Schematy lib

Https://github.com/schematics/schematics

Pozwala na tworzenie typowanych struktur danych, które mogą serializować/deserializować z Pythona do Javascript, np:

class MapPrice(Model):
    price_before_vat = DecimalType(serialized_name='priceBeforeVat')
    vat_rate = DecimalType(serialized_name='vatRate')
    vat = DecimalType()
    total_price = DecimalType(serialized_name='totalPrice')
 1
Author: Iain Hunter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-01 13:30:43

Wolę unikać re, jeśli to możliwe:

myString="ThisStringIsCamelCase" ''.join(['_'+i.lower() if i.isupper() else i for i in myString]).lstrip('_') 'this_string_is_camel_case'

 1
Author: otocan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-07 11:13:58

Tyle skomplikowanych metod... Po prostu znajdź całą grupę "zatytułowaną" i dołącz jej wariant w dolnej obudowie z podkreśleniem.

>>> import re
>>> def camel_to_snake(string):
...     groups = re.findall('([A-z0-9][a-z]*)', string)
...     return '_'.join([i.lower() for i in groups])
...
>>> camel_to_snake('ABCPingPongByTheWay2KWhereIsOurBorderlands3???')
'a_b_c_ping_pong_by_the_way_2_k_where_is_our_borderlands_3'

Jeśli nie chcesz tworzyć liczb takich jak pierwszy znak grupy lub oddzielna grupa-możesz użyć maski ([A-z][a-z0-9]*).

 1
Author: unitto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-01 12:41:24

Horrendalny przykład użycia wyrażeń regularnych (możesz łatwo to wyczyścić:)):

def f(s):
    return s.group(1).lower() + "_" + s.group(2).lower()

p = re.compile("([A-Z]+[a-z]+)([A-Z]?)")
print p.sub(f, "CamelCase")
print p.sub(f, "getHTTPResponseCode")

Działa jednak dla getHTTPResponseCode!

Alternatywnie, używając lambda:

p = re.compile("([A-Z]+[a-z]+)([A-Z]?)")
print p.sub(lambda x: x.group(1).lower() + "_" + x.group(2).lower(), "CamelCase")
print p.sub(lambda x: x.group(1).lower() + "_" + x.group(2).lower(), "getHTTPResponseCode")

EDIT: powinno być również dość łatwo zauważyć, że jest miejsce na poprawę w przypadku takich przypadków jak "Test", ponieważ podkreślenie jest bezwarunkowo wstawiane.

 0
Author: Matthew Iselin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-24 02:15:44

Oto coś, co zrobiłem, aby zmienić nagłówki w pliku rozdzielanym tabulatorami. Pomijam część, w której edytowałem tylko pierwszą linię pliku. Możesz łatwo dostosować go do Pythona za pomocą biblioteki re. Obejmuje to również oddzielanie liczb (ale utrzymuje cyfry razem). Zrobiłem to w dwóch krokach, ponieważ było to łatwiejsze niż mówienie mu, aby nie umieszczał podkreślenia na początku linii lub tabulacji.

Krok Pierwszy...znajdź wielkie litery lub liczby całkowite poprzedzone małymi literami i poprzedzają je podkreśleniem:

Szukaj:

([a-z]+)([A-Z]|[0-9]+)

Zamiennik:

\1_\l\2/
Krok Drugi...weź powyższe i uruchom je ponownie, aby przekonwertować wszystkie wielkie litery na małe:

Szukaj:

([A-Z])

Zamiennik (to odwrotny ukośnik, małe litery L, odwrotny ukośnik, jeden):

\l\1
 0
Author: Joe Tricarico,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-09 22:41:32

Szukałem rozwiązania tego samego problemu, poza tym, że potrzebowałem łańcucha; np.

"CamelCamelCamelCase" -> "Camel-camel-camel-case"

Zaczynając od ładnych dwu wyrazowych rozwiązań tutaj, wymyśliłem co następuje:

"-".join(x.group(1).lower() if x.group(2) is None else x.group(1) \
         for x in re.finditer("((^.[^A-Z]+)|([A-Z][^A-Z]+))", "stringToSplit"))

Większość skomplikowanej logiki polega na unikaniu małych liter pierwszego słowa. Oto prostsza wersja, jeśli nie masz nic przeciwko zmianie pierwszego słowa:

"-".join(x.group(1).lower() for x in re.finditer("(^[^A-Z]+|[A-Z][^A-Z]+)", "stringToSplit"))

Oczywiście, można wstępnie skompilować wyrażenia regularne lub połączyć z podkreśleniem zamiast myślnika, jak omówiono w drugim rozwiązania.

 0
Author: Jim Pivarski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-31 20:55:29

Zwięzły bez wyrażeń regularnych, ale Httpresponse_code=>httpresponse_code:

def from_camel(name):
    """
    ThisIsCamelCase ==> this_is_camel_case
    """
    name = name.replace("_", "")
    _cas = lambda _x : [_i.isupper() for _i in _x]
    seq = zip(_cas(name[1:-1]), _cas(name[2:]))
    ss = [_x + 1 for _x, (_i, _j) in enumerate(seq) if (_i, _j) == (False, True)]
    return "".join([ch + "_" if _x in ss else ch for _x, ch in numerate(name.lower())])
 0
Author: Dantalion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-09 09:42:24

Bez biblioteki:

def camelify(out):
    return (''.join(["_"+x.lower() if i<len(out)-1 and x.isupper() and out[i+1].islower()
         else x.lower()+"_" if i<len(out)-1 and x.islower() and out[i+1].isupper()
         else x.lower() for i,x in enumerate(list(out))])).lstrip('_').replace('__','_')

Trochę ciężki, ale

CamelCamelCamelCase ->  camel_camel_camel_case
HTTPRequest         ->  http_request
GetHTTPRequest      ->  get_http_request
getHTTPRequest      ->  get_http_request
 0
Author: bibmartin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-27 14:27:01

Bardzo ładny RegEx zaproponowany na tej stronie :

(?<!^)(?=[A-Z])

Jeśli python ma metodę String Split, powinna ona działać...

W Języku Java:

String s = "loremIpsum";
words = s.split("(?&#60;!^)(?=[A-Z])");
 0
Author: Jmini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-19 20:08:28

Ta prosta metoda powinna wykonać zadanie:

import re

def convert(name):
    return re.sub(r'([A-Z]*)([A-Z][a-z]+)', lambda x: (x.group(1) + '_' if x.group(1) else '') + x.group(2) + '_', name).rstrip('_').lower()
  • szukamy wielkich liter, które są poprzedzone dowolną liczbą (lub zerem) wielkich liter, a następnie dowolną liczbą małych znaków.
  • podkreślenie jest umieszczane tuż przed wystąpieniem ostatniej wielkiej litery znalezionej w grupie, i można je umieścić przed tą wielką literą, jeśli jest poprzedzona innymi wielkimi literami.
  • jeśli są końcowe podkreślniki, usuń je.
  • Wreszcie, cały łańcuch wyniku zostanie zmieniony na małe litery.

(zaczerpnięte z tutaj , Zobacz przykład pracy online )

 0
Author: Mathieu Rodic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-19 20:52:33
def convert(name):
    return reduce(
        lambda x, y: x + ('_' if y.isupper() else '') + y, 
        name
    ).lower()

A jeśli chcemy przykryć sprawę z już-nie-cameled input:

def convert(name):
    return reduce(
        lambda x, y: x + ('_' if y.isupper() and not x.endswith('_') else '') + y, 
        name
    ).lower()
 0
Author: dmrz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-13 08:52:54
def convert(camel_str):
    temp_list = []
    for letter in camel_str:
        if letter.islower():
            temp_list.append(letter)
        else:
            temp_list.append('_')
            temp_list.append(letter)
    result = "".join(temp_list)
    return result.lower()
 0
Author: JohnBoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-06 05:18:27

Na wypadek, gdyby ktoś musiał przekształcić kompletny plik źródłowy, oto skrypt, który to zrobi.

# Copy and paste your camel case code in the string below
camelCaseCode ="""
    cv2.Matx33d ComputeZoomMatrix(const cv2.Point2d & zoomCenter, double zoomRatio)
    {
      auto mat = cv2.Matx33d::eye();
      mat(0, 0) = zoomRatio;
      mat(1, 1) = zoomRatio;
      mat(0, 2) = zoomCenter.x * (1. - zoomRatio);
      mat(1, 2) = zoomCenter.y * (1. - zoomRatio);
      return mat;
    }
"""

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

def lines(str):
    return str.split("\n")

def unlines(lst):
    return "\n".join(lst)

def words(str):
    return str.split(" ")

def unwords(lst):
    return " ".join(lst)

def map_partial(function):
    return lambda values : [  function(v) for v in values]

import functools
def compose(*functions):
    return functools.reduce(lambda f, g: lambda x: f(g(x)), functions, lambda x: x)

snake_case_code = compose(
    unlines ,
    map_partial(unwords),
    map_partial(map_partial(snake_case)),
    map_partial(words),
    lines
)
print(snake_case_code(camelCaseCode))
 0
Author: Pascal T.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-18 15:29:31

[[2]}miałem z tym całkiem sporo szczęścia:

import re
def camelcase_to_underscore(s):
    return re.sub(r'(^|[a-z])([A-Z])',
                  lambda m: '_'.join([i.lower() for i in m.groups() if i]),
                  s)

To oczywiście może być zoptymalizowane dla prędkości a mały bit, jeśli chcesz.

import re

CC2US_RE = re.compile(r'(^|[a-z])([A-Z])')

def _replace(match):
    return '_'.join([i.lower() for i in match.groups() if i])

def camelcase_to_underscores(s):
    return CC2US_RE.sub(_replace, s)
 -1
Author: codekoala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-11 18:17:16

Użyj: str.capitalize() Aby przekonwertować pierwszą literę łańcucha (zawartą w zmiennej str) na wielką literę i zwraca cały łańcuch.

Przykład: Polecenie: "Witam".kapitalizuj() Wyjście: Hello

 -3
Author: Arshin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-18 06:07:33