在大写字母之前插入空格的pythonic方式

时间:2008-10-13 21:16:40

标签: python regex text-files

我有一个文件格式我正在通过python脚本进行修改。我在这个文件中有几个驼峰字符串,我只想在大写字母之前插入一个空格 - 所以“WordWordWord”变成“Word Word Word”。

我有限的正则表达式体验刚刚停止在我身上 - 有人会想到一个像样的正则表达式来做这个,或者(更好的是)是否有更多的pythonic方法来做到这一点,我错过了?

10 个答案:

答案 0 :(得分:33)

你可以尝试:

>>> re.sub(r"(\w)([A-Z])", r"\1 \2", "WordWordWord")
'Word Word Word'

答案 1 :(得分:25)

如果有连续的首都,则Gregs结果可以 不是你想要的,因为\ w消耗了特征 在要更换的空白信件前面。

>>> re.sub(r"(\w)([A-Z])", r"\1 \2", "WordWordWWWWWWWord")
'Word Word WW WW WW Word'

后视可以解决这个问题:

>>> re.sub(r"(?<=\w)([A-Z])", r" \1", "WordWordWWWWWWWord")
'Word Word W W W W W W Word'

答案 2 :(得分:10)

也许更短:

>>> re.sub(r"\B([A-Z])", r" \1", "DoIThinkThisIsABetterAnswer?")

答案 3 :(得分:8)

.NET - How can you split a “caps” delimited string into an array?

上查看我的回答

修改:或许最好将其添加到此处。

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

例如:

"SimpleHTTPServer" => ["Simple", "HTTP", "Server"]

答案 4 :(得分:4)

使用正则表达式,您可以执行此操作:

re.sub('([A-Z])', r' \1', str)

当然,这只适用于ASCII字符,如果你想做Unicode,它是一个全新的蠕虫: - )

答案 5 :(得分:4)

也许你会对不使用regexp的单线程实现感兴趣:

''.join(' ' + char if char.isupper() else char.strip() for char in text).strip()

答案 6 :(得分:2)

如果你有缩写词,你可能不希望它们之间有空格。这个两阶段正则表达式将保持首字母缩略词的完整性(并且还将标点符号和其他非大写字母视为添加空格的东西):

re_outer = re.compile(r'([^A-Z ])([A-Z])')
re_inner = re.compile(r'(?<!^)([A-Z])([^A-Z])')
re_outer.sub(r'\1 \2', re_inner.sub(r' \1\2', 'DaveIsAFKRightNow!Cool'))

输出结果为:'Dave Is AFK Right Now! Cool'

答案 7 :(得分:0)

我同意正则表达式解决方案是最简单的,但我不会说它是最pythonic。

怎么样:

text = 'WordWordWord'
new_text = ''

for i, letter in enumerate(text):
    if i and letter.isupper():
        new_text += ' '

    new_text += letter

答案 8 :(得分:0)

我认为正则表达式是这里的方法,但只是为了给出一个纯粹的python版本,没有(希望)任何问题ΤΖΩΤΖΙΟΥ指出:

def splitCaps(s):
    result = []
    for ch, next in window(s+" ", 2):
        result.append(ch)
        if next.isupper() and not ch.isspace():
            result.append(' ')
    return ''.join(result)

window()是一个实用程序函数,用于在项目的滑动窗口上操作,定义为:

import collections, itertools

def window(it, winsize, step=1):
    it=iter(it)  # Ensure we have an iterator
    l=collections.deque(itertools.islice(it, winsize))
    while 1:  # Continue till StopIteration gets raised.
        yield tuple(l)
        for i in range(step):
            l.append(it.next())
            l.popleft()

答案 9 :(得分:0)

对于旧线程 - 想尝试满足我的一个要求的选项。当然,re.sub() 是一个很酷的解决方案,但如果不(或不应该)导入 re 模块,也会得到一个 1 liner。

st = 'ThisIsTextStringToSplitWithSpace'
print(''.join([' '+ s if s.isupper()  else s for s in st]).lstrip())