Sostituisci pattern in una stringa

Realizziamo uno script con una funzione sostituisci che prenda in input una stringa di testo, una stringa da cercare, una nuova stringa, e restituisca una stringa derivata dalla stringa originale dove tutte le occorrenze del pattern da cercare sono state sostituite dalla stringa nuova. Per esempio, nel caso stringa=”ooooo”, pattern = “oo” e nuovopattern = “ca”, la funzione deve restituire “cacao”.

Soluzione

Il problema non è esattamente banale per un alunno alle prime armi, che sia di scuola superiore che universitario. Occorrono più funzioni e accorgimenti per giungere ad un algoritmo efficace. L’idea alla base potrebbe essere:

  • ciclo cercando nella stringa il pattern
  • se esiste, individuo la posizione della lettera iniziale
  • sostituisco il nuovo pattern al vecchio

Per semplicità dividiamo le due funzionalità “esiste pattern” e “posizione pattern” con due funzioni Python. Potremmo agire con una unica funzione semplicemente “posizione pattern”. Questa infatti scorre la stringa e cerca la prima ripetizione del pattern restituendo l’indice lettera da dove comincia. Ritorna -1 se non trova nulla essendo un valore arbitrario. La funzione esiste fa la stessa cosa per certi versi ma torna vero o falso a seconda che trovi una ripetizione del pattern. Potremmo tranquillamente usare solo la prima delle due visto che comunque c’è un indicatore di ritorno che ci da o meno l’esistenza. Per completezza le inseriamo entrambe.

Vediamone una delle due. L’idea alla base è di scorrere tutta la parola/stringa iniziale. In realtà non serve scorrerla tutta perché il pattern deve essere completamente incluso nella parola quindi possiamo fermarci a cercare alla lungheza della parola meno quella del patetrn. Usiamo un indice numerico con range per procedere. A questo punto controllo le lettere del pattern se sono uguali a blocchi successivi di lettere usando un indice ulteriore che aumento manualmente mano a mano che trovo letetre uguali. Se arrivo a trovare tante lettere quante il pattern allora ho trovato un blocco di lettere uguali al pattern stesso e posso ritornare l’indice del primo ciclo che si era fermato per controllare la corrispondenza del secondo ciclo. Se il blocco controllato fallisce, resetto il conteggio delle lettere uguali e procedo alla lettera successiva nella parola controllando ancora che questa sia l’inizio o meno di un blocco pari al pattern. E così via.

def posizione(stringa, pattern):
    for i in range(0, len(stringa)-len(pattern)):
        contalettere = 0
        j = i #parto dalla lettera in cui mi trovo
        for lettera in pattern:
            if lettera == stringa[j]:
                contalettere += 1
                j += 1
        if contalettere == len(pattern):
            return i
    return -1

Codice

Il listato completo con programma main e funzioni di supporto.

def esiste(stringa, pattern):
    for i in range(0, len(stringa)-len(pattern)):
        contalettere = 0
        j = i #parto dalla lettera in cui mi trovo
        for lettera in pattern:
            if lettera == stringa[j]:
                contalettere += 1
                j += 1
        if contalettere == len(pattern):
            return True
        contalettere = 0 #da resettare ogni blocco controllato
    return False

def posizione(stringa, pattern):
    for i in range(0, len(stringa)-len(pattern)):
        contalettere = 0
        j = i #parto dalla lettera in cui mi trovo
        for lettera in pattern:
            if lettera == stringa[j]:
                contalettere += 1
                j += 1
        if contalettere == len(pattern):
            return i
        contalettere = 0 #da resettare ogni blocco controllato
    return -1


def sostituisci(stringa, nuovopattern, posizione):
    nuovaparola = ""

    #copio la parte che non va sostituita
    for i in range(0, posizione):
        nuovaparola += stringa[i]

    #inserisco il pattern nella posizione
    nuovaparola += nuovopattern

    #copio la parte rimannte della parola dopo la sostituzione
    for i in range(posizione + len(nuovopattern), len(stringa)):
        nuovaparola += stringa[i]

    return nuovaparola


if __name__ == "__main__":
    stringa = "ooooo"
    pattern = "oo"
    nuovopattern = "ca"
    #print(sostituisci("pippo", "aa",2))
    while esiste(stringa, pattern):
        pos = posizione(stringa, pattern)
        stringa = sostituisci(stringa, nuovopattern,pos)
    print(stringa)    #atteso cacao

Ultima modifica 14 Marzo 2024