2010-03-31 19 views
72

C'è un modo rapido in Python per sostituire le stringhe ma, invece di ricominciare dall'inizio come replace, a partire dalla fine? Ad esempio:rreplace - Come sostituire l'ultima occorrenza di un'espressione in una stringa?

>>> 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

Buona domanda, a giudicare dalle complicate soluzioni a un problema così semplice. –

risposta

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 Penso che anche questo sarà abbastanza veloce. –

+6

Molto bello! In un benchmark non scientifico di sostituzione dell'ultima occorrenza di un'espressione in una stringa tipica del mio programma (> 500 caratteri), la soluzione era tre volte più veloce della soluzione di Alex e quattro volte più veloce della soluzione di Mark. Grazie a tutti per le vostre risposte! – Barthelemy

+0

grazie per il risultato del benchmark –

7

Non ho intenzione di fingere che questo sia il modo più efficiente per farlo, ma è un modo semplice. Si inverte tutte le stringhe in questione, esegue una sostituzione ordinaria utilizzando str.replace sulle corde invertite, poi inverte il risultato di nuovo nel senso giusto:

>>> 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

Ecco una soluzione ricorsiva al 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

Se si sa che la stringa 'vecchio' non contiene caratteri speciali che si possono fare con una regex:

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