Trovare l'ultima occorrenza della sottostringa nella stringa, sostituirla


Risposte:


163

Questo dovrebbe bastare

old_string = "this is going to have a full stop. some written sstuff!"
k = old_string.rfind(".")
new_string = old_string[:k] + ". - " + old_string[k+1:]

1
Grazie mille amico. Dovrò studiarlo per un minuto ... questo sta utilizzando le fette, giusto?
Adam Magyar

@AdamMagyar sì, il contenitore [a: b] divide dall'indice a fino a b-1 del contenitore. Se "a" viene omesso, il valore predefinito è 0; se "b" viene omesso, il valore predefinito è len (contenitore). L'operatore più si limita a concatenare. La funzione rfind come hai sottolineato restituisce l'indice attorno al quale dovrebbe avvenire l'operazione di sostituzione.
Aditya Sihag

26

Per sostituire da destra:

def replace_right(source, target, replacement, replacements=None):
    return replacement.join(source.rsplit(target, replacements))

In uso:

>>> replace_right("asd.asd.asd.", ".", ". -", 1)
'asd.asd.asd. -'

1
Mi piace decisamente questa soluzione ma avere il replacements=Noneparametro mi sembra un errore perché se il parametro viene omesso la funzione darà un errore (provato in Python 2.7). Suggerirei di rimuovere il valore predefinito, impostarlo su -1 (per sostituzioni illimitate) o meglio farlo replacements=1(che penso dovrebbe essere il comportamento predefinito per questa particolare funzione in base a ciò che vuole l'OP). Secondo i documenti questo parametro è opzionale, ma deve essere un int se fornito.
remarkov

Nel caso in cui qualcuno vuole una battuta per questo: ". -".join("asd.asd.asd.".rsplit(".", 1)). Tutto quello che stai facendo è eseguire una divisione della stringa dal lato destro per 1 occorrenza e unire di nuovo la stringa usando la sostituzione.
bsplosion il

14

Userei una regex:

import re
new_list = [re.sub(r"\.(?=[^.]*$)", r". - ", s) for s in old_list]

2
Questa è l'unica risposta che funziona se non ci sono punti. Però userei un lookahead:\.(?=[^.]*$)
georg

6

Una linea sarebbe:

str=str[::-1].replace(".",".-",1)[::-1]


1
Questo è sbagliato . Stai invertendo la stringa, sostituendola e quindi invertendola. Stai facendo .replacesu una stringa invertita. Entrambe le stringhe passate replacedevono essere anch'esse invertite. Altrimenti, quando inverti la stringa una seconda volta, le lettere che hai appena inserito saranno al contrario. Puoi usarlo solo se stai sostituendo una lettera con una lettera, e anche in questo caso non lo inserirò nel tuo codice nel caso in cui qualcuno dovesse cambiarlo in futuro e inizi a chiedersi perché una parola è scritta sdrawkcab.
Boris

1

È possibile utilizzare la funzione sottostante che sostituisce la prima occorrenza della parola da destra.

def replace_from_right(text: str, original_text: str, new_text: str) -> str:
    """ Replace first occurrence of original_text by new_text. """
    return text[::-1].replace(original_text[::-1], new_text[::-1], 1)[::-1]

0
a = "A long string with a . in the middle ending with ."

# se vuoi trovare l'indice dell'ultima occorrenza di qualsiasi stringa, nel nostro caso # troveremo l'indice dell'ultima occorrenza di con

index = a.rfind("with") 

# il risultato sarà 44, poiché l'indice inizia da 0.


-1

Approccio naïve:

a = "A long string with a . in the middle ending with ."
fchar = '.'
rchar = '. -'
a[::-1].replace(fchar, rchar[::-1], 1)[::-1]

Out[2]: 'A long string with a . in the middle ending with . -'

La risposta di Aditya Sihag con un singolo rfind:

pos = a.rfind('.')
a[:pos] + '. -' + a[pos+1:]

Questo inverte anche la stringa di sostituzione. Oltre a questo, è una ripetizione della risposta di root e, come ho detto lì, piuttosto inefficiente.
Gareth Latty

@ Lattyware Vuoi dire che si inverte a?
Alex L

Voglio dire che si inverte '. -'nell'output.
Gareth Latty

Aspettarsi solo che l'utente inverta manualmente la stringa letterale non è una grande idea: è incline a errori e poco chiara.
Gareth Latty

@ Lattyware d'accordo. Ne ho fatto una var. (Mi rendo conto che è un metodo inefficiente e non è adatto in tutti i casi - il tuo replace_rightè molto più carino)
Alex L
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.