2010-03-31 10 views
72

¿Existe alguna manera rápida en Python para reemplazar cadenas pero, en lugar de comenzar desde el principio como replace, comenzando desde el final? Por ejemplo:rreplace - ¿Cómo reemplazar la última aparición de una expresión en una cadena?

>>> def rreplace(old, new, occurrence) 
>>>  ... # Code to replace the last occurrences of old by new 

>>> '<div><div>Hello</div></div>'.rreplace('</div>','</bad>',1) 
>>> '<div><div>Hello</div></bad>' 
+3

Buena pregunta, a juzgar por las complicadas soluciones a un problema tan simple. –

Respuesta

112
>>> def rreplace(s, old, new, occurrence): 
... li = s.rsplit(old, occurrence) 
... return new.join(li) 
... 
>>> s 
'1232425' 
>>> rreplace(s, '2', ' ', 2) 
'123 4 5' 
>>> rreplace(s, '2', ' ', 3) 
'1 3 4 5' 
>>> rreplace(s, '2', ' ', 4) 
'1 3 4 5' 
>>> rreplace(s, '2', ' ', 0) 
'1232425' 
+0

+1 Creo que esto será bastante rápido también. –

+6

¡Muy bonito! En un punto de referencia no científico de reemplazar la última aparición de una expresión en una cadena típica en mi programa (> 500 caracteres), su solución fue tres veces más rápida que la solución de Alex y cuatro veces más rápida que la solución de Mark. ¡Gracias a todos por sus respuestas! – Barthelemy

+0

gracias por el resultado de referencia –

7

No voy a pretender que esta es la manera más eficiente de hacerlo, pero es una manera simple. Se revierte todas las cadenas en cuestión, lleva a cabo una sustitución ordinaria utilizando str.replace en las cuerdas invierte, entonces se invierte el resultado de nuevo en el sentido correcto:

>>> def rreplace(s, old, new, count): 
...  return (s[::-1].replace(old[::-1], new[::-1], count))[::-1] 
... 
>>> rreplace('<div><div>Hello</div></div>', '</div>', '</bad>', 1) 
'<div><div>Hello</div></bad>' 
1

Aquí es una solución recursiva del problema:

def rreplace(s, old, new, occurence = 1): 

    if occurence == 0: 
     return s 

    left, found, right = s.rpartition(old) 

    if found == "": 
     return right 
    else: 
     return rreplace(left, old, new, occurence - 1) + new + right 
3

Si sabe que la cadena 'viejo' no contiene ningún carácter especial que puede hacer con una expresión regular:

In [44]: s = '<div><div>Hello</div></div>' 

In [45]: import re 

In [46]: re.sub(r'(.*)</div>', r'\1</bad>', s) 
Out[46]: '<div><div>Hello</div></bad>' 
Cuestiones relacionadas