Apri il menu principale

PartireModifica

Per avvicinarsi al mondo dei bot si può partire leggendo:

Replace.pyModifica

 Lo stesso argomento in dettaglio: mw:Manual:Pywikipediabot/replace.py/it.

Si possono fare tante (ma davvero tante) cose con lo script Replace.py di PyWikipedia e un uso avanzato delle regular expression (anche dette "regex").

Se ci si vuole cimentare suggerisco innanzitutto l'approfondita lettura di http://www.regular-expressions.info (anche i comandi più astrusi prima o poi vi serviranno) e del manuale in italiano di Replace.py che contiene tanti utili quanto misconosciuti parametri.

User-fixes.pyModifica

 Lo stesso argomento in dettaglio: mw:Manual:Pywikipediabot/user-fixes.py.

Se questo file vi manca, potete farlo creare automaticamente lanciando "generate_user_files.py"

Il file user-fixes.py è un comodo contenitore per mantenere in ordine le collezioni di regex e le relative eccezioni che si andranno ad utilizzare con replace.py.

Per richiamare una determinata sostituzione inserita in user-fixes.py è sufficiente digitare:

replace.py -fix:esempio1 -xml:ecc.ecc...

Come fare per...Modifica

Gestire bene gli a capoModifica

Individuate gli a capo con \r?\n piuttosto che con \n o \r\n. Vi accorgerete che magicamente molti problemi scompariranno.

Operare su un particolare parametro di un templateModifica

Supponiamo che vogliate trovare ed eliminare un particolare parametro non valorizzato di un particolare template che genera una tabella sinottica. Bisogna innanzitutto considerare che 1) il template sinottico potrebbe essere ripetuto più di una volta 2) non vogliamo andare accanto a parametri omonimi di altri template. Un possibile approccio è il seguente:

(u"({{[Gg]ruppo([\W\w](?!\n}})(?!{{[Gg]ruppo))*\r?\n) *\| *Parametro tal dei tali *= *\r?\n", ur'\1'),

Osservazioni: come si può notare (?!\n}}) potrebbe creare problemi in caso di chiusura del template senza le }} all'inizio di una nuova riga e un successivo template con un parametro omonimo. Un approccio più prudente può essere quello di inserire (?!}}): così facendo però la ricerca del parametro da individuare si fermerà alle prime doppie graffe di chiusura che incontra, che magari appartengono ad un altro template inserito tra i parametri (es.{{coord}}).

Individuare porzioni ripetuteModifica

Spesso risulta utile individuare porzioni ripetute di testo, ma la relativa sintassi da usare in replace.py non è molto conosciuta. Questa regex ad esempio sostituisce "tam tam" con "tam!":

(u'(tam) \\1', ur'\1!'),

Una regex più utile ad esempio è questa: individua lettere ripetute tre volte all'interno di una parola, tipico caso di errore di battitura. Esempio: repubbblica.

(u'([a-zA-Z])(?!\\1)(?![xXVIiy])([a-z])\\2\\2(?!\\2)([a-z])', ur'\1\2\2\3'),

Aggiungere qualcosa in fondo ad una voceModifica

(u"^([\W\w]*)$", ur"\1[[questo lo voglio in fondo]]")

^ e $ sono delle anchor. Sostanzialmente cattura tutta la voce dentro il gruppo 1. Usa [\W\w]* anziché .* per evitare il problema del parametro -dotall. Leggi di più sulle anchor.

Spostare qualcosa in fondo alla voce ma sopra gli interwikiModifica

Questa regex prende le categorie contenute nel campo |Categorie del template Bio e le mette in fondo alla voce prima però degli interwiki. Notare che per funzionare il gruppo 3 deve essere non greedy.

(u"(\| *[Cc]ategorie *= *)(?! )(?![Nn][Oo])((?:[\W\w](?!\n\|)){0,400}?)((?:\r?\n *\|| *\|\r?\n|\r?\n? *\|?}})[\W\w]+?)((?:\[\[(?![Cc]ategoria)[\w-]{2,15}:[^:\]]+\]\] *(?:\r?\n)*)+)$", ur"\1no\3\2\n\n\4"),

Per ovviare al fatto che la voce potrebbe anche non contenere alcun interwiki è necessario inserire un segnaposto (e poi rimuoverlo).

(u"^([\W\w]*)$", ur"\1\n[[it:segnaposto]]"),
(u"(\| *[Cc]ategorie *= *)(?! )(?![Nn][Oo])((?:[\W\w](?!\n\|)){0,400}?)((?:\r?\n *\|| *\|\r?\n|\r?\n? *\|?}})[\W\w]+?)((?:\[\[(?![Cc]ategoria)[\w-]{2,15}:[^:\]]+\]\] *(?:\r?\n)*)+)$", ur"\1no\3\2\n\n\4"),
(u"\n\[\[it:segnaposto\]\]", ur""),

Etichettare i gruppi da sostituireModifica

A volte si ha l'esigenza di dare un vero nome ai vari gruppi da sostituire perché magari sono tanti o perché data la complessità della regex diventa molto scomodo usare i classici \1, \2, \3, ecc.

Sintassi classica:

(u'(parol)a', ur'\1e'),

Sintassi con le etichette:

(u'(?P<gruppo>parol)a', ur'\g<gruppo>e'),

Inserire tra le esclusioni i nomifile delle immaginiModifica

Quando si fanno le sostituzioni, magari di errori comuni, è sempre bene assicurarsi di non modificare ad esempio i nomifile delle immagini.

Per evitarlo si può inserire ad esempio tra le esclusioni, nell'array 'inside', la seguente riga:

r'\[\[([Ff]ile|[Ii]mmagine|[Ii]mage):[^\]\|]+\|',

Il problema è che non sempre le immagini vengono inserite con questa sintassi. A volte appaiono più subdolamente (dal nostro punto di vista) come valori di parametri all'interno di template. In questo caso un'esclusione più generica come questa può essere di aiuto:

ur'[^\r\n]{,80}\.([Gg][iI][Ff]|[Pp][Nn][Gg]|[Jj][Pp][Ee]?[Gg]|[Ss][Vv][Gg])',

In pratica esclude dalle sostituzioni tutto il testo, fino ad una distanza di 80 caratteri o fino all'inizio della riga, che precede una delle estensioni tipiche di un'immagine.

Inserire tra le esclusioni gli indirizzi webModifica

In maniera del tutto analoga al caso precedente:

ur'http://[^ \r\n]{,90}',

Convertire il campo "generi musicali"Modifica

Quando ho dovuto convertire il campo "Generi musicali = ..." del template gruppo in "genere = ...", "nota genere = ...", "genere2 = ...", "nota genere2 = ...", ... , "genere9 = ...", "nota genere9 = ...", ho usato un approccio a singola regex (singola ma se scorrete vedrete che è lunghetta). Ecco la prima versione semplificata senza la gestione dei campi "genere altro".

(u"\|generi musicali *= *(?:\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g1>[^\]\n\|]{0,99})(?:\]\]|)(?P<c1> *<!--[^>\n]+-->|) *(?P<n1>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *(?:\[?\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g2>[^\]\n\|]{0,99})(?:\]\]|)(?P<c2> *<!--[^>\n]+-->|) *(?P<n2>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *(?:\[?\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g3>[^\]\n\|]{0,99})(?:\]\]|)(?P<c3> *<!--[^>\n]+-->|) *(?P<n3>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *(?:\[?\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g4>[^\]\n\|]{0,99})(?:\]\]|)(?P<c4> *<!--[^>\n]+-->|) *(?P<n4>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *(?:\[?\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g5>[^\]\n\|]{0,99})(?:\]\]|)(?P<c5> *<!--[^>\n]+-->|) *(?P<n5>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *(?:\[?\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g6>[^\]\n\|]{0,99})(?:\]\]|)(?P<c6> *<!--[^>\n]+-->|) *(?P<n6>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *(?:\[?\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g7>[^\]\n\|]{0,99})(?:\]\]|)(?P<c7> *<!--[^>\n]+-->|) *(?P<n7>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *(?:\[?\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g8>[^\]\n\|]{0,99})(?:\]\]|)(?P<c8> *<!--[^>\n]+-->|) *(?P<n8>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *(?:\[?\[\[|\[\[(?:[^\]\|]+\||)|)(?P<g9>[^\]\n\|]{0,99})(?:\]\]|)(?P<c9> *<!--[^>\n]+-->|) *(?P<n9>(?:<[rR][eE][fF][^\n\<]+(?:</[rR][eE][fF]>|/>))+|) *(?:[\-‐‑⁃−–—―−,;/]|<[bB][rR] ?/?>|, *<[bB][rR] ?/?>|(?<=[fF]/>)|(?<=[fF]>)|(?<=[fF]/> )|(?<=[fF]> )|) *\r?\n", ur'|genere = \g<g1>\g<c1>\n|nota genere = \g<n1>\n|genere2 = \g<g2>\g<c2>\n|nota genere2 = \g<n2>\n|genere3 = \g<g3>\g<c3>\n|nota genere3 = \g<n3>\n|genere4 = \g<g4>\g<c4>\n|nota genere4 = \g<n4>\n|genere5 = \g<g5>\g<c5>\n|nota genere5 = \g<n5>\n|genere6 = \g<g6>\g<c6>\n|nota genere6 = \g<n6>\n|genere7 = \g<g7>\g<c7>\n|nota genere7 = \g<n7>\n|genere8 = \g<g8>\g<c8>\n|nota genere8 = \g<n8>\n|genere9 = \g<g9>\g<c9>\n|nota genere9 = \g<n9>\n'),

Come si può vedere tutti i gruppi ricevono un'etichetta (vedi sopra).

EsempiModifica