Utensa:Alebot/Scripts
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?
tla()
[canbia]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