camelcasing – Elegant Python function to convert CamelCase to snake_case?

camelcasing – Elegant Python function to convert CamelCase to snake_case?

Camel case to snake case

import re

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

If you do this many times and the above is slow, compile the regex beforehand:

pattern = re.compile(r(?<!^)(?=[A-Z]))
name = pattern.sub(_, name).lower()

To handle more advanced cases specially (this is not reversible anymore):

def camel_to_snake(name):
    name = re.sub((.)([A-Z][a-z]+), r1_2, name)
    return re.sub(([a-z0-9])([A-Z]), r1_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

To add also cases with two underscores or more:

def to_snake_case(name):
    name = re.sub((.)([A-Z][a-z]+), r1_2, name)
    name = re.sub(__([A-Z]), r_1, name)
    name = re.sub(([a-z0-9])([A-Z]), r1_2, name)
    return name.lower()

Snake case to camel case

name = snake_case_name
name = .join(word.title() for word in name.split(_))
print(name)  # SnakeCaseName

Theres an inflection library in the package index that can handle these things for you. In this case, youd be looking for inflection.underscore():

>>> inflection.underscore(CamelCase)
camel_case

camelcasing – Elegant Python function to convert CamelCase to snake_case?

I dont know why these are all so complicating.

for most cases, the simple expression ([A-Z]+) will do the trick

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

To ignore the first character simply add look behind (?!^)

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

If you want to separate ALLCaps to all_caps and expect numbers in your string you still dont need to do two separate runs just use | This expression ((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z])) can handle just about every scenario in the book

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

It all depends on what you want so use the solution that best suits your needs as it should not be overly complicated.

nJoy!

Leave a Reply

Your email address will not be published.