首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优雅的Python函数将CamelCase转换为snake_case?

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

Stack Overflow用户
提问于 2009-07-24 08:22:02
回答 30查看 242.2K关注 0票数 332

示例:

代码语言:javascript
复制
>>> convert('CamelCase')
'camel_case'
EN

回答 30

Stack Overflow用户

回答已采纳

发布于 2009-07-24 14:25:14

驼箱到蛇箱

代码语言:javascript
复制
import re

name = 'CamelCaseName'
name = re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
print(name)  # camel_case_name

如果您多次执行此操作,并且上述操作速度较慢,请提前编译regex:

代码语言:javascript
复制
pattern = re.compile(r'(?<!^)(?=[A-Z])')
name = pattern.sub('_', name).lower()

要特别处理更高级的情况(这不再是可逆的):

代码语言:javascript
复制
def camel_to_snake(name):
  name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
  return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()

print(camel_to_snake('camel2_camel2_case'))  # camel2_camel2_case
print(camel_to_snake('getHTTPResponseCode'))  # get_http_response_code
print(camel_to_snake('HTTPResponseCodeXYZ'))  # http_response_code_xyz

要同时添加具有两个或更多下划线的案例:

代码语言:javascript
复制
def to_snake_case(name):
    name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
    name = re.sub('__([A-Z])', r'_\1', name)
    name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name)
    return name.lower()

蛇箱到骆驼箱

代码语言:javascript
复制
name = 'snake_case_name'
name = ''.join(word.title() for word in name.split('_'))
print(name)  # SnakeCaseName
票数 970
EN

Stack Overflow用户

发布于 2013-06-27 03:34:35

在包索引中有一个inflection library,它可以为您处理这些事情。在本例中,您将查找inflection.underscore()

代码语言:javascript
复制
>>> inflection.underscore('CamelCase')
'camel_case'
票数 245
EN

Stack Overflow用户

发布于 2012-10-13 05:17:16

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

对于大多数情况,简单的表达式([A-Z]+)就可以做到这一点

代码语言:javascript
复制
>>> 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'

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

代码语言:javascript
复制
>>> 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]))就可以处理本书中的几乎所有场景

代码语言:javascript
复制
>>> 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!

票数 134
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1175208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档