find_stringa()

canbia

MediaWiki è un codice "male conformato". :-( .

find_stringa() è un'utile script che estrae una stringa che inizi con inizio e finisca con fine, utile a ripescare molte cose in un testo: templates generici o specifici, wikilinks, e qualsiasi altra cosa abbia un inizio e una fine. Ma... la vecchia versione di find_stringa() si incantava nel caso di ricerche di stringhe con codice annidato. Es: restituiva benissimo {{Centrato|bla bla...}} e anche bla bla... da clippete cloppete {{Centrato|bla bla...}} clippete cloppete.. ma si incantava nel restituire {{Centrato|{{Sc|bla bla...}}}} da clippete cloppete {{Centrato|{{Sc|bla bla...}}}} clippete cloppete.. per ovvi motivi: aimè, restituiva {{Centrato|{{Sc|bla bla...}}

La nuova versione non si fa ingannare dall'annidamento; tuttavia qualcosa mi dice che è bene fare un preliminare "test di correttezza codice" sul testo da trattare, ossia verificare che il numero di graffe (nell'esempio) aperte e chiuse sia pari.

Segue codice.

Gradita traduzione in js (ma forse ce la faccio...) . ;-)

def find_stringa(stringa,idi,idf,dc=0,x=None,side="left"):
    if side=="right":
        idip=stringa.rfind(idi)
    else:
        idip=stringa.find(idi)
    idfp=stringa.find(idf,idip+len(idi))+len(idf)
    if idip>-1 and idfp>0:
        if x!=None:
            while stringa[idip:idfp].count(x)>stringa[idip:idfp].count(idf):
                if stringa[idip:idfp].count(x)>stringa[idip:idfp].count(idf):
                    idfp=stringa.find(idf,idfp)+len(idf)
                
        if dc==0:
            vvalore=stringa[idip+len(idi):idfp-len(idf)]
        else:
            vvalore=stringa[idip:idfp]
    else:
        vvalore=""
    return vvalore

def produci_lista(testo,idi,idf,dc=1,inizio=None):
    t=testo[:]
    lista=[]
    while not find_stringa(t,idi,idf)=="":
        el=find_stringa(t,idi,idf,1,x=inizio)
        #print "elemento:",el
        t=t.replace(el,"")
        #print el
        if dc==0:
            el=find_stringa(el,idi,idf,0,x=inizio)
        #print el
        #print
        lista.append(el)
    return lista

Esempi:

>>> a="aaa bbb ccc {{Ri|94|{{smaller|LEGGENDA PRIMA}}}}aaa bbb ccc "
>>> find_stringa(a,"{{Ri|","}}",1,"{{")
'{{Ri|94|{{smaller|LEGGENDA PRIMA}}}}'

a="aaa bbb ccc <div>94<div>smaller<div>LEGGENDA</div> PRIMA</div></div>aaa bbb ccc "
>>> find_stringa(a,"<div","</div>",1,"<div")
'<div>94<div>smaller<div>LEGGENDA</div> PRIMA</div></div>'

>>> a="aaa bbb ccc {{Ri|94|{{smaller|LEGGENDA PRIMA}}}}aaa {{smaller|{{sc|LEGGENDA PRIMA}}}}bbb ccc "
>>> produci_lista(a,"{{","}}",1,"{{")
['{{Ri|94|{{smaller|LEGGENDA PRIMA}}}}', '{{smaller|{{sc|LEGGENDA PRIMA}}}}']

E' o non è carino?

Questo è il "cuore" del motore di semantizzazione su it.source. Riceve in ingresso il testo di un template, e restituisce un dizionario python in cui le chiavi sono i nomi dei parametri, e i valori sono i valori dei parametri. Poi, del dizionario si fa quello che si vuole. Restituisce il nome del template nella key aggiuntiva "nome template". Accetta template e wikilink annidati nei parametri. Resiste a eventuali spazi bianchi nelle righe parametro. ;-)

Funzioni secondarie richiamate: produci_lista() e find_stringa()

Esempio:

>>> tla("{{Test|uno={{{1|1}}}|due=[[2|2]]}}")
{'due': '[[2|2]]', 'nome template': 'Test', 'uno': '{{{1|1}}}'}


def tla(template): #riceve un template con parentesi graffe e restituisce un dizionario delle sue parti
    template=template[2:-2]
    lista=produci_lista(template,"{{{","}}}",1)+produci_lista(template,"[[","]]",1)
    for i in lista:
        template=template.replace(i,i.replace("|","{{!}}"))
    lista=produci_lista(template,"{{","}}",1)
    for i in lista:
        template=template.replace(i,i.replace("|","{{!}}"))
                      
    template=template.split("|") # splitting elementi
    for i in range(len(template)):
        template[i]=template[i].strip() #eliminazione spazi testa e coda
    el={}
    el["nome template"]=template[0]
    n=1
    for i in range(1,len(template)):
        elc=template[i].split("=",1)
        if len(elc)==1:
            el[str(n)]=elc[0].replace("{{!}}","|").strip()
        else:
            el[elc[0].strip()]=elc[1].replace("{{!}}","|").strip()
    return el

def produci_lista(testo,idi,idf,dc=0):
    t=testo[:]
    lista=[]
    while not find_stringa(t,idi,idf)=="":
        el=find_stringa(t,idi,idf,1)
        t=t.replace(el,"")
        #print el
        if dc==0:
            el=find_stringa(el,idi,idf,0)
        #print el
        #print
        lista.append(el)
    return lista

def find_stringa(stringa,idi,idf,dc=0,side="left"):
    if side=="right":
        idip=stringa.rfind(idi)
    else:
        idip=stringa.find(idi)
    idfp=stringa.find(idf,idip+len(idi))+len(idf)
    if idip>-1 and idfp>0:
        if dc==0:
            vvalore=stringa[idip+len(idi):idfp-len(idf)]
        else:
            vvalore=stringa[idip:idfp]
    else:
        vvalore=""
    return vvalore

Traesto fora da Wikipèdia - L'ençiclopedia łìbara e cołaboradiva in łéngua Vèneta "https://vec.wikisource.org/w/index.php?title=Utensa:Alebot/Scripts&oldid=37421"