例子:
>>> convert('CamelCase')
'camel_case'
例子:
>>> convert('CamelCase')
'camel_case'
当前回答
def convert(name):
return reduce(
lambda x, y: x + ('_' if y.isupper() else '') + y,
name
).lower()
如果我们需要覆盖一个已经没有驼峰输入的情况:
def convert(name):
return reduce(
lambda x, y: x + ('_' if y.isupper() and not x.endswith('_') else '') + y,
name
).lower()
其他回答
在包索引中有一个inflection库可以为您处理这些事情。在这种情况下,您将寻找inflection.underscore():
>>> inflection.underscore('CamelCase')
'camel_case'
我也在寻找同样问题的解决方案,只不过我需要一条链子;如。
"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"))
当然,您可以预先编译正则表达式,或者像其他解决方案中讨论的那样,使用下划线而不是连字符连接正则表达式。
简洁,没有正则表达式,但HTTPResponseCode=> 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())])
在标准库中没有,但我发现这个模块似乎包含您需要的功能。
为了好玩:
>>> 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'
或者,更有趣的是:
>>> 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'