Skip to content

Instantly share code, notes, and snippets.

@dsuch
Created February 11, 2013 14:08
Show Gist options
  • Save dsuch/4754601 to your computer and use it in GitHub Desktop.
Save dsuch/4754601 to your computer and use it in GitHub Desktop.
A Python function to uncamelify CamelCaseNames
# Use it under the Python license
import re
_uncamelify_re = re.compile(r'((?<=[a-z])[A-Z]|(?<!\A)[A-Z](?=[a-z]))')
# Inspired by http://stackoverflow.com/a/9283563
def uncamelify(s, separator='-', elem_func=unicode.lower):
""" Converts a CamelCaseName into a more readable one, e.g.
will turn ILikeToReadWSDLDocsNotReallyNOPENotMeQ into
i-like-to-read-wsdl-docs-not-really-nope-not-me-q or a similar one,
depending on the value of separator and elem_func.
"""
return separator.join(elem_func(elem) for elem in re.sub(_uncamelify_re, r' \1', s).split())
original = u'ILikeToReadWSDLDocsNotReallyNOPENotMeQ'
expected1 = 'i-like-to-read-wsdl-docs-not-really-nope-not-me-q'
expected2 = 'I_LIKE_TO_READ_WSDL_DOCS_NOT_REALLY_NOPE_NOT_ME_Q'
assert uncamelify(original) == expected1
assert uncamelify(original, '_', unicode.upper) == expected2
@lonetwin
Copy link

Here is the re.VERBOSE version:

_uncamelify_re = re.compile(
                    r'''(
                        (?<=[a-z])[A-Z]        # match a uppercase letter only if it follows a lower case letter
                        |                      # OR        
                        (?<!\A)                # at the start of a word
                            [A-Z]              #   match an uppercase letter,
                                (?=[a-z])      #     only if it is followed by a lower case letter

                    )''', re.VERBOSE)

# Note, that since in this method, you are matching just the first upper-case 
# letter not followed by another uppercase letter, and then in
# ``re.sub(..., ' \1' ...)`` you are substituting the match with "space+match" 
# (unlike the re.split() or re.findall() method, which I suggested, which 
# matches and splits), you could've also done:

return elem_func( re.sub(_uncamelify_re, r'%s\1' % seperator, original) )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment