为了账号安全,请及时绑定邮箱和手机立即绑定

优雅的Python函数将CamelCase转换为snake_case?

优雅的Python函数将CamelCase转换为snake_case?

偶然的你 2019-08-23 15:47:42
优雅的Python函数将CamelCase转换为snake_case?例:>>> convert('CamelCase')'camel_case'
查看完整描述

3 回答

?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

这非常彻底:


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

适用于所有这些(并且不会损害已经未出版的版本):


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

或者,如果你打算多次调用它,你可以预编译正则表达式:


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

不要忘记导入正则表达式模块


import re


查看完整回答
反对 回复 2019-08-23
?
aluckdog

TA贡献1847条经验 获得超7个赞

我不知道为什么这些都如此复杂。


对于大多数情况,简单的表达式([A-Z]+)将起到作用


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

要忽略第一个字符,只需在后面添加外观 (?!^)


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

如果你想将ALLCaps分离到all_caps并期望你的字符串中的数字,你仍然不需要做两个单独的运行只需使用|这个表达式((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))几乎可以处理书中的每个场景


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

这一切都取决于你想要什么,所以使用最适合你需求的解决方案,因为它不应该过于复杂。


的nJoy!


查看完整回答
反对 回复 2019-08-23
  • 3 回答
  • 0 关注
  • 671 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信