Python: convert camel case to space delimited using RegEx and taking Acronyms into account

后端 未结 10 1902
逝去的感伤
逝去的感伤 2020-12-29 04:38

I am trying to convert camel case to space separated values using python. For example:

divLineColor -> div Line Color

This lin

相关标签:
10条回答
  • 2020-12-29 04:54

    I don't think you can do it using a regular expression because you need to remember the previous element in order to do it for all cases. I think the following function works for all cases. For example, it converts 'AbcdEfgHIJKlmno' to 'Abcd Efg HIJ Klmno'

    def camel_case_to_phrase(s):
      prev = None
      t = []
      n = len(s)
      i = 0
    
      while i < n:
        next_char = s[i+1] if i < n -1 else ''
        c = s[i]
        if prev is None:
            t.append(c)
        elif c.isupper() and prev.isupper():
            if next_char.islower():
                t.append(' ')
                t.append(c)
            else:
                t.append(c)
        elif c.isupper() and not prev.isupper():
            t.append(' ')
            t.append(c)
        else:
            t.append(c)
        prev = c
        i = i +1
    
    return "".join(t)
    
    0 讨论(0)
  • 2020-12-29 04:56
    >>> def unCamel(x): return reduce(lambda a,b: a + ((b.upper() == b and (len(a) and a[-1].upper() != a[-1])) and (' ' + b) or b), x, '')
    ... 
    >>> 
    >>> unCamel("simpleBigURL")
    'simple Big URL'
    >>> unCamel("URL")
    'URL'
    >>> unCamel("url")
    'url'
    >>> unCamel("uRl")
    'u Rl'
    
    0 讨论(0)
  • 2020-12-29 04:57

    This should work with 'divLineColor', 'simpleBigURL', 'OldHTMLFile' and 'SQLServer'.

    label = re.sub(r'((?<=[a-z])[A-Z]|(?<!\A)[A-Z](?=[a-z]))', r' \1', label)
    

    Explanation:

    label = re.sub(r"""
            (            # start the group
                # alternative 1
            (?<=[a-z])  # current position is preceded by a lower char
                        # (positive lookbehind: does not consume any char)
            [A-Z]       # an upper char
                        #
            |   # or
                # alternative 2
            (?<!\A)     # current position is not at the beginning of the string
                        # (negative lookbehind: does not consume any char)
            [A-Z]       # an upper char
            (?=[a-z])   # matches if next char is a lower char
                        # lookahead assertion: does not consume any char
            )           # end the group""",
        r' \1', label, flags=re.VERBOSE)
    

    If a match is found it is replaced with ' \1', which is a string consisting of a leading blank and the match itself.

    Alternative 1 for a match is an upper character, but only if it is preceded by a lower character. We want to translate abYZ to ab YZ and not to ab Y Z.

    Alternative 2 for a match is an upper character, but only if it is followed by a lower character and not at the start of the string. We want to translate ABCyz to AB Cyz and not to A B Cyz.

    0 讨论(0)
  • 2020-12-29 04:58

    I couldnt get a really nice regex, but this worked decently.

    ([a-z]+)([A-Z][a-z]+)?([A-Z][a-z]+)?([A-Z][a-z]+)?([A-Z][a-z]+)?

    Breaking it down it is:

    ([a-z]+) Any series of lowercase characters

    ([A-Z][a-z]+)? Any uppercase character followed by 1 or more lowercase characters. This is optional

    Then I repeated the second group 4 times. This will only work if you dont have any more than 4 "sections" or uppercase characters. Add or take away that regex grouping as necessary. It will work if there less than this number (i.e. it will work on divLineColor) This will not match on words that are all uppercase.

    0 讨论(0)
  • 2020-12-29 05:05

    Other method:

    def solution(s):
        return ''.join(' ' + c if c.isupper() else c for c in s)
    print(solution("mehdHidi"))
    
    0 讨论(0)
  • 2020-12-29 05:06

    I know, it's not regex. But, you can also use map like this

    >>> s = 'camelCaseTest'
    >>> ''.join(map(lambda x: x if x.islower() else " "+x, s))
    'camel Case Test'
    
    0 讨论(0)
提交回复
热议问题