2010-11-10 2 views
24

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

import re 
s = 'start TT end' 
re.sub(r'([A-Z]){2}', r"\1", s) 
>>> 'start T end' 

Как я могу сделать «\ 1» нижний чехол? Должен ли я использовать регулярное выражение для этого?

+0

Не знаю, как сделать это в нижнем регистре, но вам следует использовать ' '([AZ]) {2}'' вместо ' '([AZ]) {2}'' заменить любой экземпляров. – khachik

+0

Ваше регулярное выражение также соответствует двум различным шапкам. –

ответ

39

Pass a function как repl аргумент. MatchObject передается этой функции и .group(1) дает первую подгруппу: в круглых скобках

import re 
s = 'start TT end' 
callback = lambda pat: pat.group(1).lower() 
re.sub(r'([A-Z]){2}', callback, s) 

EDIT
И да, вы должны использовать ([A-Z])\1 вместо ([A-Z]){2}, чтобы не матча, например AZ. (См @ bobince-х answer.)

import re 
s = 'start TT end' 
re.sub(r'([A-Z])\1', lambda pat: pat.group(1).lower(), s) # Inline 

Дает:

'start t end' 
+0

Спасибо, я ценю вашу помощь. – ajt

+0

@ajt Добро пожаловать. – jensgram

1

Вы можете сделать это с помощью регулярного выражения, просто передать функцию в качестве замены, как the docs говорят. Проблема заключается в вашей схеме.

Как бы то ни было, ваш шаблон соответствует прогонам любой две заглавные буквы. Я оставлю фактический шаблон вам, но он начинается с AA|BB|CC|.

6

Вы не можете изменить регистр в заменяющей строке. Вы должны были бы функцию замены:

>>> def replacement(match): 
...  return match.group(1).lower() 
... 
>>> re.sub(r'([A-Z])\1', replacement, 'start TT end') 
'start t end' 
0

Параметр «РЕПЛ», который идентифицирует замена может быть либо строкой (как вы его здесь) или функцию. Это будет делать то, что вы хотите:

import re 

def toLowercase(matchobj): 
    return matchobj.group(1).lower() 

s = 'start TT end' 
re.sub(r'([A-Z]){2}', toLowercase, s) 
>>> 'start t end' 
0

Попробуйте это:

def tol(m): 
    return m.group(0)[0].lower() 

s = 'start TTT AAA end' 
re.sub(r'([A-Z]){2,}', tol, s) 

Обратите внимание, что это не заменяет опалить заглавные буквы. Если вы хотите это сделать, используйте r'([A-Z]){1,}'.

+0

OP говорит: * повторяйте дважды * – SilentGhost

+0

@SilentGhost. Моя вина. re должен быть как предложено Ignacio, если не следует прикасаться к одиночным верхним символам. – khachik

+0

, если вы посмотрите, а ответы bobince и jens вы видите более короткий способ сделать это. – SilentGhost

0

ВНИМАНИЕ! Этот пост не имеет права на запрос. Продолжайте свою ответственность!

Я не знаю, насколько возможны угловые случаи, но это то, как нормальный Python делает мою наивную кодировку.

import string 
s = 'start TT end AAA BBBBBBB' 
for c in string.uppercase: 
    s = s.replace(c+c,c.lower()) 
print s 
""" Output: 
start t end aA bbbB 
""" 

 Смежные вопросы

  • Нет связанных вопросов^_^