Я ищу питоновский способ вставить пробел перед заглавными буквами

У меня есть файл, формат которого я изменяю через python script. У меня есть несколько верблюжьих строк в этом файле, где я просто хочу вставить одно пробел перед заглавной буквой, поэтому "WordWordWord" становится "Word Word Word".

Мой ограниченный опыт регулярного выражения просто остановился на мне - может ли кто-то подумать о приличном регулярном выражении, чтобы сделать это, или (еще лучше) есть ли более питонический способ сделать это, что мне не хватает?

Ответы

Ответ 1

Вы можете попробовать:

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

Ответ 2

Если есть последовательные капиталы, то результат Грегса может не то, что вы ищете, так как \w потребляет caracter перед заменяемым письмом.

>>> 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'

Ответ 3

Возможно, короче:

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

Ответ 5

С помощью регулярных выражений вы можете сделать это:

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

Конечно, это будет работать только для символов ASCII, если вы хотите сделать Unicode это совершенно новая возможность червей: -)

Ответ 6

Возможно, вам будет интересна реализация с одним liner без использования regexp:

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

Ответ 7

Если у вас есть аббревиатуры, вам, вероятно, не нужны пробелы между ними. Это двухэтапное регулярное выражение будет содержать аббревиатуры без изменений (а также обрабатывать знаки препинания и другие буквы, отличные от прописных, как что-то, чтобы добавить пробел):

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'

Ответ 8

Я согласен, что решение регулярных выражений является самым простым, но я бы не сказал, что это самый пифонический.

Как насчет:

text = 'WordWordWord'
new_text = ''

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

    new_text += letter

Ответ 9

Я думаю, что регулярные выражения - это путь сюда, но просто для того, чтобы дать чистую версию python без (надеюсь) любой из проблем, которые TΖΩΤΖΙΟΥ указал:

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()