例子:

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

当前回答

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

其他回答

我也在寻找同样问题的解决方案,只不过我需要一条链子;如。

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

从这两个词的解决方案开始,我想到了以下几点:

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

最复杂的逻辑是避免小写第一个单词。如果你不介意改变第一个词,这里有一个更简单的版本:

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

当然,您可以预先编译正则表达式,或者像其他解决方案中讨论的那样,使用下划线而不是连字符连接正则表达式。

轻度改编自https://stackoverflow.com/users/267781/matth 谁使用发电机。

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

Stringcase是我的首选库;例如:

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

这么多复杂的方法…… 只需找到所有“标题”组,并加入其小写变体与下划线。

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

如果你不想让数字像组的第一个字符或单独的组-你可以使用([A-z][a-z0-9]*)掩码。

这个简单的方法应该可以做到:

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

我们寻找前面有任意数量的(或零)大写字母,后面有任意数量的小写字符的大写字母。 在组中发现的最后一个大写字母之前放置下划线,如果前面有其他大写字母,则可以在该大写字母之前放置下划线。 如果后面有下划线,删除它们。 最后,整个结果字符串被改为小写。

(从这里开始,见在线工作示例)