例子:

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

当前回答

没有任何库:

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('__','_')

有点重,但是

CamelCamelCamelCase ->  camel_camel_camel_case
HTTPRequest         ->  http_request
GetHTTPRequest      ->  get_http_request
getHTTPRequest      ->  get_http_request

其他回答

没有任何库:

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('__','_')

有点重,但是

CamelCamelCamelCase ->  camel_camel_camel_case
HTTPRequest         ->  http_request
GetHTTPRequest      ->  get_http_request
getHTTPRequest      ->  get_http_request

如果你使用谷歌的(几乎)确定性骆驼案例算法,那么就不需要处理像HTMLDocument这样的东西,因为它应该是HTMLDocument,那么这种基于正则表达式的方法很简单。它用下划线替换所有的大写字母或数字。Note不处理多位数数字。

import re

def to_snake_case(camel_str):
    return re.sub('([A-Z0-9])', r'_\1', camel_str).lower().lstrip('_')

一个使用正则表达式的可怕例子(你可以很容易地清理:)):

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

但适用于getHTTPResponseCode !

或者,使用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")

编辑:对于像“Test”这样的情况,应该也很容易看到有改进的空间,因为下划线是无条件插入的。

我不知道为什么使用两个.sub()调用?:)我不是正则表达式大师,但我简化了这个函数,这是适合我的特定需求,我只是需要一个解决方案,将camelCasedVars从POST请求转换为vars_with_下划线:

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

它不能使用像getHTTPResponse这样的名字,因为我听说这是一个糟糕的命名惯例(应该像getHTTPResponse一样,很明显,它更容易记住这个形式)。

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