2015-09-22 2 views
2

У меня есть строка: HotelCityClass. Я хочу добавить пробел между буквами в верхнем регистре (кроме первого). т.е. Hotel City Class.Форматировать строку, добавив пробел перед каждой строчной буквой

Я попытался использовать повторно

re.sub (г '[A-Z]', '', str_name)

Но это заменяет только каждый верхний регистр. Правильно, быстрый подход re?

ответ

3

Вы можете использовать опережения регулярное выражение:

import re 
regex = re.compile(ur'(?!^)(?=[A-Z])', re.MULTILINE) 
str = u"HotelCityClass" 

result = re.sub(regex, " ", str) 

Выход:

Hotel City Class 

RegEx Demo

RegEx Распад:

(?!^)  # negative lookahead to assert that we are not at start 
(?=[A-Z]) # positive lookahead to assert that next position is an uppercase letter 

Замена - это просто пробел, если вышеприведенные утверждения проходят.

+0

Что такое '' ur''? – Prometheus

+3

'r' используется для сырых строк, а' u' для поддержки Unicode. – anubhava

2

Если вам приходится иметь дело с CAMEL словами, вы можете использовать следующее регулярное выражение:

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

Он захватывает строчную букву и следующую заглавную один, а затем в замене, можно добавить обратные ссылки к захваченным группам (\1 и \2).

import re 
p = re.compile(r'([a-z])([A-Z])') 
test_str = "HotelCityClass" 
result = re.sub(p, r"\1 \2", test_str) 
print(result) 

См IDEONE demo

Обратите внимание, что в случае, если вы хотите просто вставить пробел перед любым капитализированных словом, не предшествуют с пробелами, я хотел бы использовать

p = re.compile(r'(\S)([A-Z])') 
result = re.sub(p, r"\1 \2", test_str) 

См another IDEONE demo

Я бы не стал смотреть в будущее, потому что они всегда затрудняют работу (хотя в этом случае воздействие слишком мало).

+0

Говоря о «fast»: ['(?! ^) (? = [AZ])'] (https://regex101.com/r/wQ8oW2/1) требуется 75 шагов, чтобы найти все совпадения в HotelCityClass, и это принимает [my '(\ S) ([AZ])' regex] (https://regex101.com/r/wQ8oW2/2) только 66 шагов.Конечно, это не средство измерения скорости, а общее представление о том, как определенное регулярное выражение работает с заданным входом. –

1

Вот ясный способ сделать это:

import re 
a = 'HotelCityClass' 
b = re.findall('[A-Z][a-z]*', a) 

c = ' '.join(b) 

print(c) 
+0

@stribizhev Извините, я имею в виду 'b': P –

+0

какая версия python? 'print (* b)' является недопустимым синтаксисом в 2.7. – Psytho

+0

@ Alex.S Я использую python 3.4, позвольте мне отредактировать мой ответ :) –

3

Еще одна через границу \B без слова, которое соответствует между двумя символами слов и двух символов без слов.

>>> s = 'HotelCityClass' 
>>> re.sub(r'\B([A-Z])', r' \1', s) 
'Hotel City Class' 
>>> re.sub(r'\B(?=[A-Z])', r' ', s) 
'Hotel City Class' 
+1

Хорошее использование '\ B' +1 – anubhava

+2

О, спасибо ..... –

0

Это должно сделать вашу работу

re.sub(r"(\w)([A-Z])", r"\1 \2", "HotelCityClass") 
>>> 'Hotel City Class' 
Смежные вопросы