2010-11-10 22 views
24

Estoy tratando de reemplazar cualquier instancia de letras mayúsculas que se repiten dos veces en una cadena con una sola instancia de esa letra en minúsculas. Estoy usando la siguiente expresión regular y es capaz de coincidir con las letras mayúsculas repetidas, pero no estoy seguro de cómo hacer que la letra que se está reemplazando en minúsculas.Uso de una expresión regular para reemplazar letras mayúsculas repetidas en python con una sola letra minúscula

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

¿Cómo puedo hacer la minúscula "\ 1"? ¿No debería usar una expresión regular para hacer esto?

+0

No sabe cómo hacer que sea minúscula, pero su debe utilizar ' '([AZ]) {2}' 'en lugar de' '([AZ]) {2}'' para sustituir a cualquier instancias. – khachik

+0

Su expresión regular también coincide con dos límites diferentes. –

Respuesta

39

Pass a function como el argumento repl. El MatchObject se pasa a esta función y .group(1) da el primer subgrupo entre paréntesis:

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

EDITAR
Y sí, se debe utilizar en lugar de ([A-Z])\1([A-Z]){2} con el fin de no partido, por ejemplo, AZ. (Ver @ bobince de answer.)

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

Da:

'start t end' 
+0

Gracias, agradezco su ayuda. – ajt

+0

@ajt De nada. – jensgram

1

Usted puede hacerlo con una expresión regular, sólo tiene que pasar una función como la sustitución como the docs dicen. El problema es tu patrón.

Como es, su patrón coincide con las ejecuciones de cualquiera dos letras mayúsculas. Dejaré el patrón real para usted, pero comienza con AA|BB|CC|.

6

No puede cambiar la caja en una cadena de reemplazo. Se necesitaría una función de sustitución:

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

El parámetro 'repl' que identifica el reemplazo puede ser una cadena (como lo tienes aquí) o una función. Esto va a hacer lo que desea:

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

Prueba esto:

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

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

Tenga en cuenta que este no reemplaza letras mayúsculas chamusquina. Si desea hacerlo, use r'([A-Z]){1,}'.

+0

OP dice: * se repiten dos veces * – SilentGhost

+0

@SilentGhost. Mi culpa. el re debería ser como lo sugiere Ignacio, si no se tocaran los caracteres superiores solos. – khachik

+0

si mira y las respuestas de bobince y jens, verá la forma más corta de hacerlo. – SilentGhost

0

¡ADVERTENCIA! Esta publicación no tiene re según lo solicitado. ¡Continúa bajo tu propia responsabilidad!

No sé cómo son posibles los casos de esquina, pero esta es la forma normal en que Python hace mi codificación ingenua.

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 
""" 
Cuestiones relacionadas