Python:使用正则表达式将驼峰命名转换为空格分隔,并考虑首字母缩写

36 投票
11 回答
20410 浏览
提问于 2025-04-16 11:57

我正在尝试用Python把驼峰命名法的字符串转换成用空格分隔的值。比如:

divLineColor -> div Line Color

这一行代码可以成功做到这一点:

label = re.sub("([A-Z])"," \g<0>",label)

我遇到的问题是像 simpleBigURL 这样的字符串,它们应该变成:

simpleBigURL -> simple Big URL

我不太确定怎么才能得到这个结果。求助!


这是我尝试过的一种方法:

label = re.sub("([a-z])([A-Z])","\g<0> \g<1>",label)

但这产生了奇怪的结果,比如:

divLineColor -> divL vineC eolor

我还在想使用 (?!...) 这种方式可能有效,但我没有成功。

11 个回答

9

我知道,这不是正则表达式。但你也可以像这样使用 map

>>> s = 'camelCaseTest'
>>> ''.join(map(lambda x: x if x.islower() else " "+x, s))
'camel Case Test'
47

这个应该可以和 'divLineColor'、'simpleBigURL'、'OldHTMLFile' 还有 'SQLServer' 一起使用。

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

解释:

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)

如果找到了匹配的内容,就会用 ' \1' 来替换它,这个字符串的开头有一个空格,后面跟着找到的匹配内容。

匹配的第一种情况是一个大写字母,但前面必须有一个小写字母。我们想把 abYZ 转换成 ab YZ,而不是 ab Y Z

匹配的第二种情况是一个大写字母,但后面必须跟着一个小写字母,并且不能出现在字符串的开头。我们想把 ABCyz 转换成 AB Cyz,而不是 A B Cyz

31

\g<0> 是指整个匹配模式的字符串,而 \g<1> 是指第一个子模式(也就是括号里的部分)匹配到的字符串。所以你应该使用 \g<1>\g<2> 来代替:

label = re.sub("([a-z])([A-Z])","\g<1> \g<2>",label)

撰写回答