2010-11-10 23 views
24

Sto tentando di sostituire qualsiasi istanza di lettere maiuscole che si ripetono due volte in una stringa con una singola istanza di quella lettera in minuscolo. Sto usando la seguente espressione regolare ed è in grado di abbinare le lettere maiuscole ripetute, ma non sono sicuro di come rendere la lettera che viene sostituita in minuscolo.Utilizzo di un'espressione regolare per sostituire lettere maiuscole ripetute in python con una singola lettera minuscola

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

Come posso rendere "\ 1" in minuscolo? Non dovrei usare un'espressione regolare per fare questo?

+0

Non so come farlo minuscolo, ma il vostro dovrebbe usare ' '([AZ]) {2,}'' invece di ' '([AZ]) {2}'' per sostituire qualsiasi le istanze. – khachik

+0

L'espressione regolare corrisponde anche a due diversi limiti. –

risposta

39

Pass a function come argomento repl. Il MatchObject viene passato a questa funzione e .group(1) dà il primo sottogruppo tra parentesi:

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

EDIT
E sì, si dovrebbe usare ([A-Z])\1 invece di ([A-Z]){2} per non partita per esempio AZ. (Vedere @ bobince di answer.)

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

Dà:

'start t end' 
+0

Grazie, apprezzo il tuo aiuto. – ajt

+0

@ajt Prego. – jensgram

1

si può fare con un'espressione regolare, basta passare una funzione come la sostituzione come the docs dicono. Il problema è il tuo modello.

Allo stato attuale, il modello corrisponde alle corse di qualsiasi due maiuscole. Lascerò il modello attuale, ma inizia con AA|BB|CC|.

6

Non è possibile modificare il caso in una stringa di sostituzione. Si avrebbe bisogno di una funzione di sostituzione:

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

Il parametro 'REPL' che identifica la sostituzione può essere una stringa (come lo avete qui) o una funzione. Questo farà quello che si desidera:

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

Prova questa:

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

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

Si noti che questo non sostituisce singe lettere maiuscole. Se vuoi farlo, usa r'([A-Z]){1,}'.

+0

OP dice: * ripetersi due volte * – SilentGhost

+0

@SilentGhost. Colpa mia. il re dovrebbe essere come suggerito da Ignacio, se non si devono toccare i singoli caratteri superiori. – khachik

+0

se guardi e le risposte di bobince's e jens vedi il modo più breve per farlo. – SilentGhost

0

ATTENZIONE! Questo post non ha re come richiesto. Continua con la tua responsabilità!

Non so quanto sia possibile i casi d'angolo, ma è normale che Python esegua la mia ingenua codifica.

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 
""" 
Problemi correlati