Python:使用正则表达式将驼峰命名转换为空格分隔,并考虑首字母缩写
我正在尝试用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)